static void asyncb_disconnect(struct connection *c,uint32_t reason) { asynsock_t asysock = (asynsock_t)c->usr_ptr; if(asysock){ if(asysock->c){ release_conn(asysock->c); asysock->c = NULL; } else if(asysock->s != INVALID_SOCK){ CloseSocket(asysock->s); asysock = INVALID_SOCK; } if(asysock->que){ struct msg_connection *msg = calloc(1,sizeof(*msg)); msg->base._ident = TO_IDENT(asysock->sident); msg->base.type = MSG_DISCONNECTED; msg->reason = reason; get_addr_remote(asysock->sident,msg->ip,32); get_port_remote(asysock->sident,&msg->port); if(0 != msgque_put_immeda(asysock->que,(lnode*)msg)) free(msg); } asynsock_release(asysock); }else { printf("fatal error\n"); exit(0); } }
int32_t asynsock_close(sock_ident s) { asynsock_t d = cast_2_asynsock(s); if(d) { int32_t ret = 0; if(!d->sndque){ active_close(d->c); ret = 1; } else { msg_t msg = calloc(1,sizeof(*msg)); msg->_ident = TO_IDENT(s); msg->type = MSG_ACTIVE_CLOSE; if(0 != msgque_put_immeda(d->sndque,(lnode*)msg)) { free(msg); ret = -2; } } asynsock_release(d); return ret; } return -1; }
int32_t asynnet_bind(msgdisp_t disp,int32_t pollerid,sock_ident sock,int8_t raw,uint32_t recv_timeout,uint32_t send_timeout) { asynsock_t asysock = cast_2_asynsock(sock); if(!asysock) return -1; struct msg_bind *msg = calloc(1,sizeof(*msg)); msg->base.type = MSG_BIND; msg->base._ident = TO_IDENT(sock); msg->recv_timeout = recv_timeout; msg->send_timeout = send_timeout; msg->raw = raw; asysock->que = disp->mq; asynnet_t asynet = disp->asynet; int32_t idx = 0;//当poller_count>1时,netpollers[0]只用于监听和connect if(pollerid <= 0 || pollerid > asynet->poller_count){ if(asynet->poller_count > 1) idx = rand()%(asynet->poller_count-1) + 1; }else idx = pollerid-1; if(0 != msgque_put_immeda(asynet->netpollers[idx].mq_in,(lnode*)msg)){ free(msg); asynsock_release(asysock); return -1; } asynsock_release(asysock); return 0; }
void _write_log(logfile_t logfile,const char *content) { uint32_t content_len = strlen(content); struct log_item *item = calloc(1,sizeof(*item) + content_len); item->_logfile = logfile; strncpy(item->content,content,content_len); int8_t ret = msgque_put_immeda(pending_log,(lnode*)item); if(ret != 0) free(item); }
int32_t push_msg(msgdisp_t disp,msg_t msg) { /*if(self && !is_vaild_ident(MSG_IDENT(msg))){ msgsender _sender = make_by_msgdisp(self); MSG_IDENT(msg) = TO_IDENT(_sender); }*/ int32_t ret = msgque_put_immeda(disp->mq,(lnode*)msg); if(ret != 0) mq_item_destroyer((void*)msg); return ret; }
int32_t asyn_send(sock_ident sock,wpacket_t wpk) { int32_t ret = -1; asynsock_t asynsock = cast_2_asynsock(sock); if(asynsock) { MSG_IDENT(wpk) = TO_IDENT(sock); ret = msgque_put_immeda(asynsock->sndque,(lnode*)wpk); asynsock_release(asynsock); } if(ret != 0) wpk_destroy(&wpk); return ret; }
static void asyncb_connect(SOCK sock,struct sockaddr_in *addr_remote,void *ud,int err) { if(sock == INVALID_SOCK){ msgque_t mq = (msgque_t)ud; //connect失败 struct msg_connection *msg = calloc(1,sizeof(*msg)); msg->base.type = MSG_CONNECT_FAIL; msg->reason = err; inet_ntop(INET,addr_remote,msg->ip,32); msg->port = ntohs(addr_remote->sin_port); if(0 != msgque_put_immeda(mq,(lnode*)msg)){ free(msg); } } else new_connection(sock,addr_remote,ud); }
void new_connection(SOCK sock,struct sockaddr_in *addr_remote,void *ud) { struct connection *c = new_conn(sock,1); c->cb_disconnect = asyncb_disconnect; asynsock_t d = asynsock_new(c,INVALID_SOCK); msgque_t mq = (msgque_t)ud; struct msg_connection *msg = calloc(1,sizeof(*msg)); msg->base._ident = TO_IDENT(d->sident); msg->base.type = MSG_ONCONNECT; get_addr_remote(d->sident,msg->ip,32); get_port_remote(d->sident,&msg->port); if(0 != msgque_put_immeda(mq,(lnode*)msg)){ asynsock_release(d); free(msg); } }
int32_t asynnet_connect(msgdisp_t disp,int32_t pollerid,const char *ip,int32_t port,uint32_t timeout) { asynnet_t asynet = disp->asynet; struct msg_connect *msg = calloc(1,sizeof(*msg)); msg->base.type = MSG_CONNECT; strcpy(msg->ip,ip); msg->port = port; msg->timeout = timeout; MSG_USRPTR(msg) = (void*)disp->mq; if(pollerid <= 0 || pollerid > asynet->poller_count) pollerid = 0; else pollerid -= 1; if(0 != msgque_put_immeda(asynet->netpollers[pollerid].mq_in,(lnode*)msg)){ free(msg); return -1; } return 0; }
static void process_msg(struct poller_st *n,msg_t msg) { if(msg->type == MSG_BIND) { //printf("MSG_BIND\n"); asynsock_t d = cast_2_asynsock(CAST_2_SOCK(msg->_ident)); if(d){ struct connection *c = d->c; socket_t s = get_socket_wrapper(c->socket); if(!s->engine){ struct msg_bind *_msgbind = (struct msg_bind*)msg; c->raw = _msgbind->raw; if(0 != n->netpoller->bind(n->netpoller,c,asyncb_process_packet,asyncb_disconnect, _msgbind->recv_timeout, _msgbind->recv_timeout ? asyncb_io_timeout:NULL, _msgbind->send_timeout, _msgbind->send_timeout ? asyncb_io_timeout:NULL)) { //绑定出错,直接关闭连接 asyncb_disconnect(c,0); }else{ d->sndque = n->mq_in; //通知逻辑绑定成功 struct msg_connection *tmsg = calloc(1,sizeof(*tmsg)); tmsg->base._ident = TO_IDENT(d->sident); tmsg->base.type = MSG_ONCONNECTED; get_addr_remote(d->sident,tmsg->ip,32); get_port_remote(d->sident,&tmsg->port); if(0 != msgque_put_immeda(d->que,(lnode*)tmsg)) free(tmsg); } } asynsock_release(d); } }else if(msg->type == MSG_CONNECT) { struct msg_connect *_msg = (struct msg_connect*)msg; if(0 != n->netpoller->connect(n->netpoller,_msg->ip,_msg->port,MSG_USRPTR(_msg),asyncb_connect,_msg->timeout)) { //connect失败 struct msg_connection *tmsg = calloc(1,sizeof(*tmsg)); tmsg->base.type = MSG_CONNECT_FAIL; tmsg->reason = errno; strcpy(tmsg->ip,_msg->ip); tmsg->port = _msg->port; msgque_t que = (msgque_t)MSG_USRPTR(_msg); if(0 != msgque_put_immeda(que,(lnode*)tmsg)){ free(tmsg); } } }else if(msg->type == MSG_ACTIVE_CLOSE) { asynsock_t d = cast_2_asynsock(CAST_2_SOCK(msg->_ident)); if(d){ active_close(d->c); asynsock_release(d); } } if(MSG_FN_DESTROY(msg)) MSG_FN_DESTROY(msg)((void*)msg); else free(msg); }