www.pudn.com > MessageQueue.zip > msgqueue.c


/* 
Copyright (C) 2004  Liu Ge 
 
This program is free software; you can redistribute it and/or 
modify it under the terms of the GNU General Public License 
as published by the Free Software Foundation; either version 2 
of the License, or (at your option) any later version. 
 
This program is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
GNU General Public License for more details. 
 
You should have received a copy of the GNU General Public License 
along with this program; if not, write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 
*/ 
#include "memmgr.h" 
#include "msgqueue.h" 
#include  
 
typedef struct 
{ 
    PVOID pData; 
    int nSize; 
}St_Message, * P_Message; 
 
P_MsgQueue MsgQueue_Create(void) 
{ 
    P_MsgQueue pMsgQueue = malloc( sizeof(St_MsgQueue) ); 
    if( pMsgQueue != NULL ) 
    { 
        List_init( pMsgQueue->MessageQueue ); 
        pMsgQueue->pQueueLock = Mutex_Create(); 
        pMsgQueue->pQueueCount = Semaphore_Create(0); 
    } 
 
    return pMsgQueue; 
} 
 
BOOL MsgQueue_Destroy( P_MsgQueue pMsgQueue ) 
{ 
    P_IntListNode p = List_getFirst( pMsgQueue->MessageQueue ); 
    while( p != NULL ) 
    { 
        List_removeFirst( pMsgQueue->MessageQueue ); 
        p = List_getFirst( pMsgQueue->MessageQueue ); 
    } 
     
    Semaphore_Destroy( pMsgQueue->pQueueCount ); 
    Mutex_Destroy( pMsgQueue->pQueueLock ); 
     
    free( pMsgQueue ); 
    return TRUE; 
} 
 
int MsgQueue_Receive( P_MsgQueue pMsgQueue, void * pBuffer, int nLimit ) 
{ 
    P_IntListNode pNode; 
    P_Message pMessage; 
     
    Semaphore_Wait( pMsgQueue->pQueueCount ); 
     
    Mutex_Hold( pMsgQueue->pQueueLock ); 
         
    pNode = List_getFirst( pMsgQueue->MessageQueue ); 
     
    pMessage = (P_Message)pNode->Data; 
    if( nLimit > pMessage->nSize ) 
    { 
        nLimit = pMessage->nSize; 
    } 
     
    memcpy( pBuffer, pMessage->pData, nLimit ); 
    free( pMessage->pData ); 
    free( pMessage ); 
     
    List_removeFirst( pMsgQueue->MessageQueue ); 
     
    free( pNode ); 
     
    Mutex_Release( pMsgQueue->pQueueLock ); 
     
    return nLimit; 
} 
 
BOOL MsgQueue_Send( P_MsgQueue pMsgQueue, const void * pBuffer, int n ) 
{ 
    P_IntListNode pNode; 
    P_Message pMessage; 
     
    pMessage = malloc( sizeof(St_Message) ); 
    if( pMessage == NULL ) 
    { 
        return FALSE; 
    } 
     
    pMessage->pData = malloc(n); 
    if( pMessage->pData == NULL ) 
    { 
        free( pMessage ); 
        return FALSE; 
    } 
 
    pNode = malloc(sizeof(St_IntListNode) ); 
    if( pNode == NULL ) 
    { 
        free( pMessage->pData ); 
        free( pMessage ); 
        return FALSE; 
    } 
     
    pMessage->nSize = n; 
     
    Mutex_Hold( pMsgQueue->pQueueLock ); 
     
    memcpy( pMessage->pData, pBuffer, n ); 
         
    pNode->Data = (int)pMessage; 
    pNode->pNext = NULL; 
 
    List_add( pMsgQueue->MessageQueue, pNode ); 
     
    Semaphore_Signal( pMsgQueue->pQueueCount ); 
     
    Mutex_Release( pMsgQueue->pQueueLock ); 
     
    return TRUE; 
}