bool MessageEndpoint::PushMessage(Message *message) { uint32_t ourSerial; bool isNewCallback = false; if(message == NULL) { return false; } { Lock shutdownLock(&m_isShutdownMutex); if(m_isShutDown) { message->DeleteContents(); delete message; return false; } } //The other endpoint must always provide a valid "our" serial number, ignore if they don't if(message->m_ourSerialNumber == 0) { message->DeleteContents(); delete message; return false; } //If this is a new conversation from the endpoint (new callback conversation) if(message->m_theirSerialNumber == 0) { isNewCallback = true; //Look up to see if there's a MessageQueue for this serial MessageQueue *queue = m_queues.GetByTheirSerial(message->m_ourSerialNumber); //If this is a brand new callback message if(queue == NULL) { ourSerial = GetNextOurSerialNum(); m_queues.AddQueue(ourSerial, message->m_ourSerialNumber); queue = m_queues.GetByOurSerial(ourSerial); //It's possible to have a race condition that would delete this MessageQueue before we could access it if(queue == NULL) { message->DeleteContents(); delete message; return false; } } if(queue->PushMessage(message)) { if(isNewCallback) { { Lock lock(&m_availableCBsMutex); m_availableCBs.push(ourSerial); } pthread_cond_signal(&m_callbackWakeupCondition); } return true; } else { return false; } } //If we got here, the message should be for an existing conversation // (IE: Both serials should be valid) MessageQueue *queue = m_queues.GetByOurSerial(message->m_theirSerialNumber); if(queue == NULL) { //If there wasn't a MessageQueue for this serial number, then this message must be late or in error message->DeleteContents(); delete message; return false; } //Update the MessageQueue to have the received "their" serial. It might not have it yet. m_queues.AddQueue(message->m_theirSerialNumber, message->m_ourSerialNumber); return queue->PushMessage(message); }