struct task_pool *task_pool_new(int nthreads) { int i; struct task_pool *pool = (struct task_pool *)malloc(struct task_pool); if (NULL == pool) { mfatal("task_pool alloc failed!"); exit(1); } pool->shutdown = 0; pool->nthreads = nthreads; pool->thread = (pthread_t)malloc(nthreads * sizeof(pthread_t)); if (NULL == pool->thread) { mfatal("thread id alloc failed!"); exit(1); } for (i = 0; i < nthreads; i++) { if (0 != pthread_create(&pool->thread[i], NULL, thread_func, NULL)) { mfatal("pthread_create failed!"); exit(1); } } pool->head = NULL; if (0 != pthread_mutex_init(&pool->lock, NULL)) { mfatal("pthread_mutex_init failed!"); exit(1); } if (0 != pthread_cond_init(&pool->cond, NULL)) { mfatal("pthread_cond_init failed!"); exit(1); } return pool; }
connector *connector_new(struct sockaddr *sa, int socklen, rpc_cb_func rpc) { connector *cr = (connector *)malloc(sizeof(connector)); if (NULL == cr) { mfatal("connector alloc failed!"); return NULL; } cr->sa = (struct sockaddr *)malloc(socklen); if (NULL == cr->sa) { mfatal("sockaddr alloc failed!"); free(cr); return NULL; } cr->cb.rpc = rpc; cr->state = STATE_NOT_CONNECTED; cr->c = NULL; memcpy(cr->sa, sa, socklen); cr->socklen = socklen; snprintf(cr->addrtext, 32, "%s:%d", inet_ntoa(((struct sockaddr_in *)(cr->sa))->sin_addr), ntohs(((struct sockaddr_in *)(cr->sa))->sin_port)); cr->timer = NULL; dispatch_conn_new(-1, 't', cr); return cr; }
listener *listener_new(struct event_base* base, struct sockaddr *sa, int socklen, user_callback *cb) { listener * l = (listener *)malloc(sizeof(listener)); if (NULL == l) { mfatal("listener alloc failed!"); return NULL; } /* listener */ struct evconnlistener *listener = evconnlistener_new_bind(base, accept_cb, (void *)l, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1, (struct sockaddr *)sa, socklen); if (NULL == listener) { mfatal("create evconnlistener failed!"); free(l); return NULL; } l->cb.type = 'l'; l->cb.rpc = cb? cb->rpc : NULL; l->cb.connect = cb ? cb->connect : NULL; l->cb.disconnect = cb ? cb->disconnect : NULL; l->l = listener; snprintf(l->addrtext, 32, "%s:%d", inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), ntohs(((struct sockaddr_in *)sa)->sin_port)); return l; }
char * estrdup(const char *str) { void *ret = strdup(str); if(!ret) mfatal("strdup", strlen(str)); return ret; }
void * erealloc(void *ptr, uint size) { void *ret = realloc(ptr, size); if(!ret) mfatal("realloc", size); return ret; }
void * emalloc(uint size) { void *ret = malloc(size); if(!ret) mfatal("malloc", size); return ret; }
void thread_init(struct event_base *main_base, int nthreads, pthread_t *th) { int i; pthread_mutex_init(&init_lock, NULL); pthread_cond_init(&init_cond, NULL); pthread_mutex_init(&cqi_freelist_lock, NULL); cqi_freelist = NULL; dispatcher_thread.base = main_base; dispatcher_thread.thread_id = pthread_self(); threads = (LIBEVENT_THREAD *)calloc(nthreads, sizeof(LIBEVENT_THREAD)); if (NULL == threads) { mfatal("allocate threads failed!"); exit(1); } for (i = 0; i < nthreads; i++) { int fds[2]; if (pipe(fds)) { mfatal("can't create notify pipe!"); exit(1); } threads[i].notify_receive_fd = fds[0]; threads[i].notify_send_fd = fds[1]; setup_thread(&threads[i]); } for (i = 0; i < nthreads; i++) { create_worker(worker_libevent, &threads[i], th + i); } pthread_mutex_lock(&init_lock); wait_for_thread_registration(nthreads); pthread_mutex_unlock(&init_lock); num_threads = nthreads; }
static void create_worker(void *(*func)(void *), void *arg, pthread_t *th) { pthread_attr_t attr; int ret; pthread_attr_init(&attr); if ((ret = pthread_create(th, &attr, func, arg)) != 0) { mfatal("pthread_create failed!"); exit(1); } }
static void setup_thread(LIBEVENT_THREAD *me) { me->base = event_base_new(); if (NULL == me->base) { mfatal("allocate event base failed!"); exit(1); } event_set(&me->notify_event, me->notify_receive_fd, EV_READ | EV_PERSIST, thread_libevent_process, me); event_base_set(me->base, &me->notify_event); if (event_add(&me->notify_event, 0) == -1) { mfatal("can't monitor libevent notify pipe!"); exit(1); } me->new_conn_queue = (struct conn_queue *)malloc(sizeof(struct conn_queue)); if (NULL == me->new_conn_queue) { mfatal("connection queue alloc failed!"); exit(EXIT_FAILURE); } cq_init(me->new_conn_queue); }
int main(int argc, char **argv) { /* open log */ if (0 != LOG_OPEN("./center", LOG_LEVEL_DEBUG, -1)) { fprintf(stderr, "open center log failed!\n"); return 1; } if (0 != check_cmd()) { return 1; } /* protobuf verify version */ GOOGLE_PROTOBUF_VERIFY_VERSION; struct event_base *main_base = event_base_new(); if (NULL == main_base) { mfatal("main_base = event_base_new() failed!"); return 1; } conn_init(); /* thread */ pthread_t worker[WORKER_NUM]; thread_init(main_base, WORKER_NUM, worker); /* signal */ struct event *signal_event; signal_event = evsignal_new(main_base, SIGINT, signal_cb, (void *)main_base); if (NULL == signal_event || 0 != event_add(signal_event, NULL)) { mfatal("create/add a signal event failed!"); return 1; } /* listener for gate */ struct sockaddr_in sa; bzero(&sa, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(44000); listener *lg = listener_new(main_base, (struct sockaddr *)&sa, sizeof(sa), gate_cb); if (NULL == lg) { mfatal("create client listener failed!"); return 1; } /* connector to center */ struct sockaddr_in csa; bzero(&csa, sizeof(csa)); csa.sin_family = AF_INET; csa.sin_addr.s_addr = inet_addr("127.0.0.1"); csa.sin_port = htons(43001); connector *ce = connector_new((struct sockaddr *)&csa, sizeof(csa), center_cb); if (NULL == ce) { mfatal("create center connector failed!"); return 1; } event_base_dispatch(main_base); for (int i = 0; i < WORKER_NUM; i++) pthread_join(worker[i], NULL); connector_free(ce); listener_free(lg); event_free(signal_event); event_base_free(main_base); /* shutdown protobuf */ google::protobuf::ShutdownProtobufLibrary(); /* close log */ LOG_CLOSE(); return 0; }