mirror of
https://github.com/haiwen/ccnet-server.git
synced 2025-09-01 12:56:27 +00:00
Initial commit of Ccnet server.
This commit is contained in:
105
lib/cevent.c
Normal file
105
lib/cevent.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
#include "include.h"
|
||||
#include "cevent.h"
|
||||
|
||||
#define CEVENT_SIZE (sizeof(CEvent))
|
||||
|
||||
typedef struct Handler {
|
||||
cevent_handler handler;
|
||||
void *handler_data;
|
||||
} Handler;
|
||||
|
||||
CEventManager* cevent_manager_new ()
|
||||
{
|
||||
CEventManager *manager;
|
||||
|
||||
manager = g_new0 (CEventManager, 1);
|
||||
pthread_mutex_init (&manager->mutex, NULL);
|
||||
manager->handler_table = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal, NULL, g_free);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
void pipe_callback (evutil_socket_t fd, short event, void *vmgr)
|
||||
{
|
||||
CEventManager *manager = (CEventManager *) vmgr;
|
||||
CEvent *cevent;
|
||||
char buf[CEVENT_SIZE];
|
||||
|
||||
if (ccnet_util_pipereadn(fd, buf, CEVENT_SIZE) != CEVENT_SIZE) {
|
||||
g_warning ("read pipe error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cevent = (CEvent *)buf;
|
||||
Handler *h = g_hash_table_lookup (manager->handler_table,
|
||||
(gconstpointer)(long)cevent->id);
|
||||
if (h == NULL) {
|
||||
g_warning ("no handler for event type %d\n", cevent->id);
|
||||
return;
|
||||
}
|
||||
|
||||
h->handler(cevent, h->handler_data);
|
||||
}
|
||||
|
||||
int cevent_manager_start (CEventManager *manager)
|
||||
{
|
||||
if (ccnet_util_pipe(manager->pipefd) < 0) {
|
||||
g_warning ("pipe error: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
event_set (&manager->event, manager->pipefd[0],
|
||||
EV_READ | EV_PERSIST, pipe_callback, manager);
|
||||
event_add (&manager->event, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t cevent_manager_register (CEventManager *manager,
|
||||
cevent_handler handler, void *handler_data)
|
||||
{
|
||||
uint32_t id;
|
||||
Handler *h;
|
||||
|
||||
h = g_new0(Handler, 1);
|
||||
h->handler = handler;
|
||||
h->handler_data = handler_data;
|
||||
|
||||
/* Since we're using 32-bit int for id, it may wrap around to 0.
|
||||
* If some caller persistently use one id, it's handler may be
|
||||
* overwritten by others.
|
||||
*/
|
||||
do {
|
||||
id = manager->next_id++;
|
||||
} while (g_hash_table_lookup (manager->handler_table, (gpointer)(long)id));
|
||||
|
||||
g_hash_table_insert (manager->handler_table, (gpointer)(long)id, h);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void cevent_manager_unregister (CEventManager *manager, uint32_t id)
|
||||
{
|
||||
g_hash_table_remove (manager->handler_table, (gpointer)(long)id);
|
||||
}
|
||||
|
||||
void
|
||||
cevent_manager_add_event (CEventManager *manager, uint32_t id,
|
||||
void *data)
|
||||
{
|
||||
pthread_mutex_lock (&manager->mutex);
|
||||
|
||||
struct CEvent cevent;
|
||||
char *buf = (char *) &cevent;
|
||||
|
||||
cevent.id = id;
|
||||
cevent.data = data;
|
||||
if (ccnet_util_pipewriten(manager->pipefd[1], buf, CEVENT_SIZE) != CEVENT_SIZE) {
|
||||
g_warning ("add event error\n");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&manager->mutex);
|
||||
}
|
Reference in New Issue
Block a user