Loading...
Searching...
No Matches
libevent.h
Go to the documentation of this file.
// Copyright 2016-2018 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LIBEVENT_H_
#define LIBEVENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <event.h>
#include <event2/thread.h>
#include "../nats.h"
typedef struct
{
natsConnection *nc;
struct event_base *loop;
struct event *read;
struct event *write;
struct event *keepActive;
} natsLibeventEvents;
// Forward declarations
natsStatus natsLibevent_Read(void *userData, bool add);
natsStatus natsLibevent_Detach(void *userData);
void
natsLibevent_Init(void)
{
#if _WIN32
evthread_use_windows_threads();
#else
evthread_use_pthreads();
#endif
}
static void
natsLibevent_ProcessEvent(evutil_socket_t fd, short event, void *arg)
{
natsLibeventEvents *nle = (natsLibeventEvents*) arg;
if (event & EV_READ)
natsConnection_ProcessReadEvent(nle->nc);
if (event & EV_WRITE)
natsConnection_ProcessWriteEvent(nle->nc);
}
static void
keepAliveCb(evutil_socket_t fd, short flags, void * arg)
{
// do nothing...
}
natsStatus
natsLibevent_Attach(void **userData, void *loop, natsConnection *nc, natsSock socket)
{
struct event_base *libeventLoop = (struct event_base*) loop;
natsLibeventEvents *nle = (natsLibeventEvents*) (*userData);
natsStatus s = NATS_OK;
// This is the first attach (when reconnecting, nle will be non-NULL).
if (nle == NULL)
{
nle = (natsLibeventEvents*) calloc(1, sizeof(natsLibeventEvents));
if (nle == NULL)
return NATS_NO_MEMORY;
nle->nc = nc;
nle->loop = libeventLoop;
nle->keepActive = event_new(nle->loop, -1, EV_PERSIST, keepAliveCb, NULL);
if (nle->keepActive == NULL)
s = NATS_NO_MEMORY;
if (s == NATS_OK)
{
struct timeval timeout;
timeout.tv_sec = 100000;
timeout.tv_usec = 0;
if (event_add(nle->keepActive, &timeout) != 0)
s = NATS_ERR;
}
}
else
{
if (nle->read != NULL)
{
event_free(nle->read);
nle->read = NULL;
}
if (nle->write != NULL)
{
event_free(nle->write);
nle->write = NULL;
}
}
if (s == NATS_OK)
{
nle->read = event_new(nle->loop, socket, EV_READ|EV_PERSIST,
natsLibevent_ProcessEvent, (void*) nle);
natsLibevent_Read((void*) nle, true);
nle->write = event_new(nle->loop, socket, EV_WRITE|EV_PERSIST,
natsLibevent_ProcessEvent, (void*) nle);
}
if (s == NATS_OK)
*userData = (void*) nle;
else
natsLibevent_Detach((void*) nle);
return s;
}
natsStatus
natsLibevent_Read(void *userData, bool add)
{
natsLibeventEvents *nle = (natsLibeventEvents*) userData;
int res;
if (add)
res = event_add(nle->read, NULL);
else
res = event_del_noblock(nle->read);
return (res == 0 ? NATS_OK : NATS_ERR);
}
natsStatus
natsLibevent_Write(void *userData, bool add)
{
natsLibeventEvents *nle = (natsLibeventEvents*) userData;
int res;
if (add)
res = event_add(nle->write, NULL);
else
res = event_del_noblock(nle->write);
return (res == 0 ? NATS_OK : NATS_ERR);
}
natsStatus
natsLibevent_Detach(void *userData)
{
natsLibeventEvents *nle = (natsLibeventEvents*) userData;
if (nle->read != NULL)
event_free(nle->read);
if (nle->write != NULL)
event_free(nle->write);
if (nle->keepActive != NULL)
{
event_active(nle->keepActive, 0, 0);
event_free(nle->keepActive);
}
free(nle);
return NATS_OK;
}
// end of libeventFunctions
#ifdef __cplusplus
}
#endif
#endif /* LIBEVENT_H_ */
natsConnection_ProcessReadEvent
NATS_EXTERN void natsConnection_ProcessReadEvent(natsConnection *nc)
Process a read event when using external event loop.
natsConnection_ProcessWriteEvent
NATS_EXTERN void natsConnection_ProcessWriteEvent(natsConnection *nc)
Process a write event when using external event loop.
natsLibevent_Init
void natsLibevent_Init(void)
Initialize the adapter.
Definition: libevent.h:58
natsLibevent_Attach
natsStatus natsLibevent_Attach(void **userData, void *loop, natsConnection *nc, natsSock socket)
Attach a connection to the given event loop.
Definition: libevent.h:98
natsLibevent_Write
natsStatus natsLibevent_Write(void *userData, bool add)
Start or stop polling on WRITE events.
Definition: libevent.h:192
natsLibevent_Read
natsStatus natsLibevent_Read(void *userData, bool add)
Start or stop polling on READ events.
Definition: libevent.h:170
natsLibevent_Detach
natsStatus natsLibevent_Detach(void *userData)
The connection is closed, it can be safely detached.
Definition: libevent.h:214
natsConnection
struct __natsConnection natsConnection
A connection to a NATS Server.
Definition: nats.h:152
natsSock
int natsSock
Definition: nats.h:50
natsStatus
natsStatus
Status returned by most of the APIs.
Definition: status.h:50
NATS_ERR
@ NATS_ERR
Generic error.
Definition: status.h:53
NATS_NO_MEMORY
@ NATS_NO_MEMORY
Definition: status.h:102
NATS_OK
@ NATS_OK
Success.
Definition: status.h:51