/* Copyright (c) 2003-2005 MySQL AB 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; version 2 of the License. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "SignalQueue.hpp" SignalQueue::SignalQueue() { m_mutex = NdbMutex_Create(); m_cond = NdbCondition_Create(); m_signalQueueHead = NULL; } SignalQueue::~SignalQueue() { { Guard g(m_mutex); while(m_signalQueueHead != NULL) delete pop(); } NdbMutex_Destroy(m_mutex); m_mutex = NULL; NdbCondition_Destroy(m_cond); m_cond = NULL; } NdbApiSignal * SignalQueue::pop() { NdbApiSignal *ret; if(m_signalQueueHead == NULL) return NULL; ret = m_signalQueueHead->signal; QueueEntry *old = m_signalQueueHead; m_signalQueueHead = m_signalQueueHead->next; delete old; return ret; } void SignalQueue::receive(void *me, NdbApiSignal *signal) { SignalQueue *q = (SignalQueue *)me; q->receive(signal); } void SignalQueue::receive(NdbApiSignal *signal) { QueueEntry *n = new QueueEntry(); n->signal = signal; n->next = NULL; Guard guard(m_mutex); if(m_signalQueueHead == NULL) { m_signalQueueHead = n; NdbCondition_Broadcast(m_cond); return; } QueueEntry *cur = m_signalQueueHead; while(cur->next != NULL) cur = cur->next; cur->next = n; NdbCondition_Broadcast(m_cond); } NdbApiSignal * SignalQueue::waitFor(int gsn, NodeId nodeid, Uint32 timeout) { Guard g(m_mutex); if(m_signalQueueHead == NULL) NdbCondition_WaitTimeout(m_cond, m_mutex, timeout); if(m_signalQueueHead == NULL) return NULL; if(gsn != 0 && m_signalQueueHead->signal->readSignalNumber() != gsn) return NULL; if(nodeid != 0 && refToNode(m_signalQueueHead->signal->theSendersBlockRef) != nodeid) return NULL; return pop(); }