int Oed_Dispatcher_stop(T _this_) { assert(_this_); item_ *item; item = Mem_calloc(1, sizeof *item, __FILE__, __LINE__); item->dispatcher = _this_; item->type = TQUIT; oe_id sid = _gen_id(_this_); item->sid = sid; #ifdef OE_USE_THREADS if (_this_->number_of_threads > 0) { _que_push(_this_, item); oe_pthread_join( _this_->thread_id, NULL ); } else { _process_que_item(_this_,item); } #else _process_que_item(_this_,item); #endif //todo: find a way to free mem from pending timer events, or flush them somehow //} return 0; }
static item_ *_create_reg_item(T _this_, oe_scalar *templ_p, oe_time dur, bool consume, user_callback *match_handler, user_callback *timeout_handler, user_callback_arg args) { assert(_this_); //todo: use pool of items and stop alloc'ing item_ *item; item = Mem_calloc(1, sizeof *item, __FILE__, __LINE__); item->dispatcher = _this_; oe_id sid = _gen_id(_this_); item->sid = sid; item->duration = dur; item->consume = consume; item->type = REG; item->object = templ_p; item->match_handler = match_handler; item->timeout_handler = timeout_handler; item->args = args; item->items = NULL; return item; }
static int _cb(struct skynet_context * ctx, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { struct gate *g = ud; if (type == PTYPE_TEXT) { _ctrl(ctx, g , msg , (int)sz); return 0; } assert(type == PTYPE_RESPONSE); struct mread_pool * m = g->pool; int connection_id = mread_poll(m,100); // timeout : 100ms if (connection_id < 0) { skynet_command(ctx, "TIMEOUT", "1"); } else { int id = g->map[connection_id].uid; if (id == 0) { id = _gen_id(g, connection_id); int fd = mread_socket(m , connection_id); struct sockaddr_in remote_addr; socklen_t len = sizeof(struct sockaddr_in); getpeername(fd, (struct sockaddr *)&remote_addr, &len); _report(g, ctx, "%d open %d %s:%u",id,fd,inet_ntoa(remote_addr.sin_addr),ntohs(remote_addr.sin_port)); } uint8_t * plen = mread_pull(m,g->header_size); if (plen == NULL) { if (mread_closed(m)) { _remove_id(g,id); _report(g, ctx, "%d close", id); } goto _break; } // big-endian int len ; if (g->header_size == 2) { len = plen[0] << 8 | plen[1]; } else { len = plen[0] << 24 | plen[1] << 16 | plen[2] << 8 | plen[3]; } void * data = mread_pull(m, len); if (data == NULL) { if (mread_closed(m)) { _remove_id(g,id); _report(g, ctx, "%d close", id); } goto _break; } _forward(ctx, g, id, data, len); mread_yield(m); _break: skynet_command(ctx, "TIMEOUT", "0"); } return 0; }
int (Oed_Dispatcher_stats)(T _this_) { assert(_this_); item_ *item; item = Mem_calloc(1, sizeof *item, __FILE__, __LINE__); item->dispatcher = _this_; item->type = DIAG; oe_id sid = _gen_id(_this_); item->sid = sid; _schedule_item(_this_, item); return 0; }
int Oed_Dispatcher_print_diag(T _this_) { assert(_this_); item_ *item; item = Mem_calloc(1, sizeof *item, __FILE__, __LINE__); item->dispatcher = _this_; item->type = DIAG; oe_id sid = _gen_id(_this_); item->sid = sid; _schedule_item(_this_, item); //todo: find a way to free mem from pending timer events, or flush them somehow //} return 0; }
static void _schedule_heartbeat( T _this_ ) { item_ *timer_item; timer_item = Mem_calloc( 1, sizeof *timer_item, __FILE__, __LINE__ ); oe_id sid = _gen_id(_this_); timer_item->sid = sid; timer_item->dispatcher = _this_; timer_item->type = HEARTBEAT; struct timeval tv; struct event *timeout; timeout = Mem_calloc(1, sizeof *timeout, __FILE__, __LINE__); event_base_set(_this_->net_obj, timeout); timer_item->timer_event = timeout; evtimer_set(timeout, _heartbeat_cb, timer_item); evutil_timerclear(&tv); tv.tv_sec = 10; event_add(timeout, &tv); }
void Oed_Dispatcher_process(T _this_, DataObject props, bool make_clone) { assert(_this_); OE_TLOG(0, "Oed_Dispatcher_process\n"); //i18n item_ *item; item = Mem_calloc(1, sizeof *item, __FILE__, __LINE__); item->dispatcher = _this_; oe_id sid = _gen_id(_this_); item->sid = sid; item->type = PROCESS; oe_scalar *propsarray = DataObject_toArray(props); if (make_clone) { oe_scalar *clone; _clone_attr_array(propsarray, &clone); item->object = clone; } else { item->object = propsarray; } item->free_alloc = make_clone; //if this is clone, the matcher must free it item->items = NULL; _schedule_item(_this_, item); }