28#define NATS_LIBUV_INCLUDE 
   33#define NATS_LIBUV_ATTACH   (1) 
   34#define NATS_LIBUV_READ     (2) 
   35#define NATS_LIBUV_WRITE    (3) 
   36#define NATS_LIBUV_DETACH   (4) 
   38struct __natsLibuvEvent;
 
   40typedef struct __natsLibuvEvent
 
   44    struct __natsLibuvEvent *next;
 
   53    uv_async_t      *scheduler;
 
   69static uv_once_t    uvOnce = UV_ONCE_INIT;
 
   70static uv_key_t     uvLoopThreadKey;
 
   75    if (uv_key_create(&uvLoopThreadKey) != 0)
 
   92    uv_once(&uvOnce, _initOnce);
 
 
  106    uv_key_set(&uvLoopThreadKey, (
void*) loop);
 
 
  110uvScheduleToEventLoop(natsLibuvEvents *nle, 
int eventType, 
bool add)
 
  112    natsLibuvEvent  *newEvent = NULL;
 
  115    newEvent = (natsLibuvEvent*) malloc(
sizeof(natsLibuvEvent));
 
  116    if (newEvent == NULL)
 
  119    newEvent->type  = eventType;
 
  121    newEvent->next  = NULL;
 
  123    uv_mutex_lock(nle->lock);
 
  125    if (nle->head == NULL)
 
  126        nle->head = newEvent;
 
  128    if (nle->tail != NULL)
 
  129        nle->tail->next = newEvent;
 
  131    nle->tail = newEvent;
 
  133    uv_mutex_unlock(nle->lock);
 
  135    res = uv_async_send(nle->scheduler);
 
  141natsLibuvPoll(uv_poll_t* handle, 
int status, 
int events)
 
  143    natsLibuvEvents *nle = (natsLibuvEvents*)handle->data;
 
  154    if (events & UV_READABLE)
 
  157    if (events & UV_WRITABLE)
 
  162uvPollUpdate(natsLibuvEvents *nle, 
int eventType, 
bool add)
 
  166    if (eventType == NATS_LIBUV_READ)
 
  169            nle->events |= UV_READABLE;
 
  171            nle->events &= ~UV_READABLE;
 
  176            nle->events |= UV_WRITABLE;
 
  178            nle->events &= ~UV_WRITABLE;
 
  182        res = uv_poll_start(nle->handle, nle->events, natsLibuvPoll);
 
  184        res = uv_poll_stop(nle->handle);
 
  193uvHandleClosedCb(uv_handle_t *handle)
 
  199uvAsyncAttach(natsLibuvEvents *nle)
 
  204    if (nle->handle != NULL)
 
  206        uv_close((uv_handle_t*) nle->handle, uvHandleClosedCb);
 
  210    nle->handle = (uv_poll_t*) malloc(
sizeof(uv_poll_t));
 
  211    if (nle->handle == NULL)
 
  216#if UV_VERSION_MAJOR <= 1 
  217        if (uv_poll_init_socket(nle->loop, nle->handle, nle->socket) != 0)
 
  219        if (uv_poll_init(nle->loop, nle->handle, nle->socket) != 0)
 
  225        && (nle->handle->data = (
void*) nle)
 
  226        && (uv_poll_start(nle->handle, UV_READABLE, natsLibuvPoll) != 0))
 
  235finalCloseCb(uv_handle_t* handle)
 
  237    natsLibuvEvents *nle = (natsLibuvEvents*)handle->data;
 
  238    natsLibuvEvent  *event;
 
  240    while ((event = nle->head) != NULL)
 
  242        nle->head = 
event->next;
 
  246    free(nle->scheduler);
 
  247    uv_mutex_destroy(nle->lock);
 
  253closeSchedulerCb(uv_handle_t* scheduler)
 
  255    natsLibuvEvents *nle = (natsLibuvEvents*) scheduler->data;
 
  257    uv_close((uv_handle_t*) nle->handle, finalCloseCb);
 
  261uvAsyncDetach(natsLibuvEvents *nle)
 
  263    uv_close((uv_handle_t*) nle->scheduler, closeSchedulerCb);
 
  267uvAsyncCb(uv_async_t *handle)
 
  269    natsLibuvEvents *nle    = (natsLibuvEvents*) handle->data;
 
  271    natsLibuvEvent  *
event  = NULL;
 
  276        uv_mutex_lock(nle->lock);
 
  283            uv_mutex_unlock(nle->lock);
 
  287        nle->head = 
event->next;
 
  288        if (event == nle->tail)
 
  291        more = (nle->head != NULL ? true : 
false);
 
  293        uv_mutex_unlock(nle->lock);
 
  297            case NATS_LIBUV_ATTACH:
 
  299                s = uvAsyncAttach(nle);
 
  302            case NATS_LIBUV_READ:
 
  303            case NATS_LIBUV_WRITE:
 
  305                s = uvPollUpdate(nle, event->type, event->add);
 
  308            case NATS_LIBUV_DETACH:
 
  345    uv_loop_t       *uvLoop = (uv_loop_t*) loop;
 
  347    natsLibuvEvents *nle    = (natsLibuvEvents*) (*userData);
 
  350    sched = ((uv_key_get(&uvLoopThreadKey) != loop) ? 
true : 
false);
 
  359        nle = (natsLibuvEvents*) calloc(1, 
sizeof(natsLibuvEvents));
 
  363        nle->lock = (uv_mutex_t*) malloc(
sizeof(uv_mutex_t));
 
  364        if (nle->lock == NULL)
 
  367        if ((s == 
NATS_OK) && (uv_mutex_init(nle->lock) != 0))
 
  371            && ((nle->scheduler = (uv_async_t*) malloc(
sizeof(uv_async_t))) == NULL))
 
  377            && (uv_async_init(uvLoop, nle->scheduler, uvAsyncCb) != 0))
 
  386            nle->scheduler->data = (
void*) nle;
 
  392        nle->socket = socket;
 
  393        nle->events = UV_READABLE;
 
  396            s = uvScheduleToEventLoop(nle, NATS_LIBUV_ATTACH, 
true);
 
  398            s = uvAsyncAttach(nle);
 
  402        *userData = (
void*) nle;
 
 
  420    natsLibuvEvents *nle = (natsLibuvEvents*) userData;
 
  424    sched = ((uv_key_get(&uvLoopThreadKey) != nle->loop) ? 
true : 
false);
 
  434    if (sched || (nle->head != NULL))
 
  435        s = uvScheduleToEventLoop(nle, NATS_LIBUV_READ, add);
 
  437        s = uvPollUpdate(nle, NATS_LIBUV_READ, add);
 
 
  453    natsLibuvEvents *nle = (natsLibuvEvents*) userData;
 
  457    sched = ((uv_key_get(&uvLoopThreadKey) != nle->loop) ? 
true : 
false);
 
  460    if (sched || (nle->head != NULL))
 
  461        s = uvScheduleToEventLoop(nle, NATS_LIBUV_WRITE, add);
 
  463        s = uvPollUpdate(nle, NATS_LIBUV_WRITE, add);
 
 
  479    natsLibuvEvents *nle = (natsLibuvEvents*) userData;
 
  483    sched = ((uv_key_get(&uvLoopThreadKey) != nle->loop) ? 
true : 
false);
 
  486    if (sched || (nle->head != NULL))
 
  487        s = uvScheduleToEventLoop(nle, NATS_LIBUV_DETACH, 
true);
 
 
 
NATS_EXTERN void natsConnection_Close(natsConnection *nc)
Closes the connection.
NATS_EXTERN void natsConnection_ProcessReadEvent(natsConnection *nc)
Process a read event when using external event loop.
NATS_EXTERN void natsConnection_ProcessWriteEvent(natsConnection *nc)
Process a write event when using external event loop.
void natsLibuv_SetThreadLocalLoop(uv_loop_t *loop)
Register the event loop with the thread running uv_run().
Definition libuv.h:104
void natsLibuv_Init(void)
Initialize the adapter.
Definition libuv.h:90
natsStatus natsLibuv_Read(void *userData, bool add)
Start or stop polling on READ events.
Definition libuv.h:418
natsStatus natsLibuv_Attach(void **userData, void *loop, natsConnection *nc, natsSock socket)
Attach a connection to the given event loop.
Definition libuv.h:343
natsStatus natsLibuv_Detach(void *userData)
The connection is closed, it can be safely detached.
Definition libuv.h:477
natsStatus natsLibuv_Write(void *userData, bool add)
Start or stop polling on WRITE events.
Definition libuv.h:451
struct __natsConnection natsConnection
A connection to a NATS Server.
Definition nats.h:152
int natsSock
Definition nats.h:50
natsStatus
Status returned by most of the APIs.
Definition status.h:50
@ NATS_ERR
Generic error.
Definition status.h:53
@ NATS_NO_MEMORY
Definition status.h:102
@ NATS_ILLEGAL_STATE
Definition status.h:88
@ NATS_OK
Success.
Definition status.h:51