#include "shmqueue.h" ShmQueue::ShmQueue(Shm *shm, ShmSlot slot, bool owner) { _shm = shm; _owner = owner; if (owner) { ShmPlace queue_place = shm->alloc(sizeof(ShmQueueStart)); shm->setSlot(slot, queue_place); ref(shm, queue_place, &_queue); _queue->first = SHM_NULL; _queue->last = SHM_NULL; _queue->count = 0; } else { ShmPlace queue_start = shm->slot(slot); ref(shm, queue_start, &_queue); } char buf[1024]; sprintf(buf, "sem_%s_%d", shm->name(), slot); _queue_sem = shm->sem(buf, owner); } ShmQueue::~ShmQueue() { if (_owner) { cleanup(); } } void ShmQueue::cleanup() { // does currently nothing delete _queue_sem; } int ShmQueue::depth() { _shm->lock(); int d = _queue->count; _shm->unlock(); return d; } void ShmQueue::enqueue(int cmd, const QString &json_data) { QByteArray b(json_data.toUtf8()); int str_place = _shm->alloc(b.size() + 1); char *s; ref(_shm, str_place, &s); memcpy(s, b.constData(), b.size()); s[b.size()] = '\0'; int item_place = _shm->alloc(sizeof(ShmQueueItem)); ShmQueueItem *item; ref(_shm, item_place, &item); item->cmd = cmd; item->data_place = str_place; item->prev = _queue->last; item->next = SHM_NULL; _shm->lock(); _queue->last = item_place; if (_queue->first == SHM_NULL) { _queue->first = _queue->last; } _queue->count += 1; _shm->unlock(); _queue_sem->post(); } bool ShmQueue::dequeue(int &cmd, QString &json_data, bool wait) { if (wait) { _queue_sem->wait(); } else { if (!_queue_sem->trywait()) { return false; } } _shm->lock(); ShmPlace item_place = _queue->first; ShmQueueItem *item; ref(_shm, item_place, &item); _queue->first = item->next; if (_queue->first == SHM_NULL) { _queue->last = SHM_NULL; } _queue->count -= 1; _shm->unlock(); ShmPlace data_place = item->data_place; char *data; ref(_shm, data_place, &data); json_data = QString::fromUtf8(data, strlen(data)); _shm->free(data_place); cmd = item->cmd; _shm->free(item_place); return true; }