File: callbackqueue.cpp

package info (click to toggle)
r-cran-httpuv 1.4.5.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 924 kB
  • sloc: ansic: 6,509; cpp: 3,478; makefile: 102; sh: 13
file content (49 lines) | stat: -rw-r--r-- 1,219 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "callbackqueue.h"
#include "tqueue.h"
#include "thread.h"
#include <boost/function.hpp>
#include <uv.h>


// This non-class function is a plain C wrapper for CallbackQueue::flush(), and
// is needed as a callback to pass to uv_async_send.
void flush_callback_queue(uv_async_t *handle) {
  CallbackQueue* wq = reinterpret_cast<CallbackQueue*>(handle->data);
  wq->flush();
}


CallbackQueue::CallbackQueue(uv_loop_t* loop) {
  ASSERT_BACKGROUND_THREAD()
  uv_async_init(loop, &flush_handle, flush_callback_queue);
  flush_handle.data = reinterpret_cast<void*>(this);
}


void CallbackQueue::push(boost::function<void (void)> cb) {
  q.push(cb);
  uv_async_send(&flush_handle);
}

void CallbackQueue::flush() {
  ASSERT_BACKGROUND_THREAD()
  boost::function<void (void)> cb;

  while (1) {
    // Do queue operations inside this guarded scope, but we'll execute the
    // callback outside of the scope, since it doesn't need to be protected,
    // and this will make it possible for the other thread to do queue
    // operations while we're invoking the callback.
    {
      guard guard(q.mutex);
      if (q.size() == 0) {
        break;
      }

      cb = q.front();
      q.pop();
    }

    cb();
  }
}