System: FixQueue

Data Structure

typedef struct fixed_queue_t {
  list_t* list;
  semaphore_t* enqueue_sem;
  semaphore_t* dequeue_sem;
  std::mutex* mutex;
  size_t capacity;

  reactor_object_t* dequeue_object;
  fixed_queue_cb dequeue_ready;
  void* dequeue_context;
} fixed_queue_t;

Initial

fixed_queue_t* fixed_queue_new(size_t capacity) {
  fixed_queue_t* ret =
      static_cast<fixed_queue_t*>(osi_calloc(sizeof(fixed_queue_t)));

  ret->mutex = new std::mutex;
  ret->capacity = capacity;

  ret->list = list_new(NULL);
  if (!ret->list) goto error;

  ret->enqueue_sem = semaphore_new(capacity);
  if (!ret->enqueue_sem) goto error;

  ret->dequeue_sem = semaphore_new(0);
  if (!ret->dequeue_sem) goto error;

  return ret;

error:
  fixed_queue_free(ret, NULL);
  return NULL;
}

EnQueue

void fixed_queue_enqueue(fixed_queue_t* queue, void* data) {
  CHECK(queue != NULL);
  CHECK(data != NULL);

  semaphore_wait(queue->enqueue_sem);

  {
    std::lock_guard<std::mutex> lock(*queue->mutex);
    list_append(queue->list, data);
  }

  semaphore_post(queue->dequeue_sem);
}

bool fixed_queue_try_enqueue(fixed_queue_t* queue, void* data) {
  CHECK(queue != NULL);
  CHECK(data != NULL);

  if (!semaphore_try_wait(queue->enqueue_sem)) return false;

  {
    std::lock_guard<std::mutex> lock(*queue->mutex);
    list_append(queue->list, data);
  }

  semaphore_post(queue->dequeue_sem);
  return true;
}

DeQueue

void* fixed_queue_dequeue(fixed_queue_t* queue) {
  CHECK(queue != NULL);

  semaphore_wait(queue->dequeue_sem);

  void* ret = NULL;
  {
    std::lock_guard<std::mutex> lock(*queue->mutex);
    ret = list_front(queue->list);
    list_remove(queue->list, ret);
  }

  semaphore_post(queue->enqueue_sem);

  return ret;
}

void* fixed_queue_try_dequeue(fixed_queue_t* queue) {
  if (queue == NULL) return NULL;

  if (!semaphore_try_wait(queue->dequeue_sem)) return NULL;

  void* ret = NULL;
  {
    std::lock_guard<std::mutex> lock(*queue->mutex);
    ret = list_front(queue->list);
    list_remove(queue->list, ret);
  }

  semaphore_post(queue->enqueue_sem);

  return ret;
}

Monitor

void fixed_queue_register_dequeue(fixed_queue_t* queue, reactor_t* reactor,
                                  fixed_queue_cb ready_cb, void* context) {
  CHECK(queue != NULL);
  CHECK(reactor != NULL);
  CHECK(ready_cb != NULL);

  // Make sure we're not already registered
  fixed_queue_unregister_dequeue(queue);

  queue->dequeue_ready = ready_cb;
  queue->dequeue_context = context;
  queue->dequeue_object =
      reactor_register(reactor, fixed_queue_get_dequeue_fd(queue), queue,
                       internal_dequeue_ready, NULL);
}

void fixed_queue_unregister_dequeue(fixed_queue_t* queue) {
  CHECK(queue != NULL);

  if (queue->dequeue_object) {
    reactor_unregister(queue->dequeue_object);
    queue->dequeue_object = NULL;
  }
}

static void internal_dequeue_ready(void* context) {
  CHECK(context != NULL);

  fixed_queue_t* queue = static_cast<fixed_queue_t*>(context);
  queue->dequeue_ready(queue, queue->dequeue_context);
}

DeIntial

void fixed_queue_free(fixed_queue_t* queue, fixed_queue_free_cb free_cb) {
  if (!queue) return;

  fixed_queue_unregister_dequeue(queue);

  if (free_cb)
    for (const list_node_t* node = list_begin(queue->list);
         node != list_end(queue->list); node = list_next(node))
      free_cb(list_node(node));

  list_free(queue->list);
  semaphore_free(queue->enqueue_sem);
  semaphore_free(queue->dequeue_sem);
  delete queue->mutex;
  osi_free(queue);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值