void mutex_print(pthread_mutex_t *m, char *txt) { if (!print_state) return; mutex_t *m_ = (mutex_t *)*m; if (m_ == NULL) { printf("M%p %d %s\n",*m,(int)GetCurrentThreadId(),txt); } else { printf("M%p %d V=%0X B=%d t=%d o=%d C=%d R=%d H=%p %s\n", *m, (int)GetCurrentThreadId(), (int)m_->valid, (int)m_->busy, m_->type, (int)GET_OWNER(m_),(int)(m_->count),(int)GET_RCNT(m_),GET_HANDLE(m_),txt); } }
void Worker::run() { int ret; __dlist_t head; __dlist_t *next; Connection *conn; NOTICE("worker is running now."); while (!_stopped) { DLIST_INIT(&head); pthread_mutex_lock(&_mutex); while (DLIST_EMPTY(&_queue)) pthread_cond_wait(&_cond, &_mutex); next = DLIST_NEXT(&_queue); DLIST_REMOVE(&_queue); pthread_mutex_unlock(&_mutex); DLIST_INSERT_B(&head, next); while (!DLIST_EMPTY(&head)) { next = DLIST_NEXT(&head); DLIST_REMOVE(next); conn = GET_OWNER(next, Connection, _list); TRACE("start to process conn, sock[%d].", conn->_sock_fd); try { ret = conn->on_process(); if (ret == 0) { conn->_status = Connection::ST_PROCESSING_REQUEST_OK; TRACE("process conn ok, sock[%d].", conn->_sock_fd); } else { conn->_status = Connection::ST_PROCESSING_REQUEST_FAIL; WARNING("failed to process conn, sock[%d], ret=%d.", conn->_sock_fd, ret); } } catch (...) { WARNING("failed to process conn, sock[%d], exception catched.", conn->_sock_fd); } _server_manager->done(conn); } } NOTICE("worker is stopped by user, exiting now."); }
int map_save(combat_game * map) { unsigned int hash; char filename[128]; char options[20]; char *map_data; int handle, a; hash = _generate_hash((char*)combat_options_string_write(map, 1)); snprintf(filename, sizeof(filename), "%s/%s.%u", GLOBAL_MAPS, map->name, hash); handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE); if (handle < 0) { snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps/%s.%u", getenv("HOME"), map->name, hash); handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE); if (handle < 0) { snprintf(filename, sizeof(filename), "%s/.ggz", getenv("HOME")); mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); snprintf(filename, sizeof(filename), "%s/.ggz/combat", getenv("HOME")); mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps", getenv("HOME")); mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps/%s.%u", getenv("HOME"), map->name, hash); handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE); if (handle < 0) { // Give up game_message ("I couldn't write the map to disk"); return -1; } } } // Width/height ggz_conf_write_int(handle, "map", "width", map->width); ggz_conf_write_int(handle, "map", "height", map->height); // Army data for (a = 0; a < 12; a++) ggz_conf_write_int(handle, "army", file_unit_name[a], map->army[map->number][a]); // Map data map_data = (char *)ggz_malloc(map->width * map->height + 1); for (a = 0; a < map->width * map->height; a++) { if (GET_OWNER(map->map[a].type) >= 0) { // Intial position! map_data[a] = GET_OWNER(map->map[a].type) + 49; } else { // Get's terrain switch (LAST(map->map[a].type)) { case T_OPEN: map_data[a] = 'O'; break; case T_NULL: map_data[a] = 'N'; break; case T_LAKE: map_data[a] = 'L'; break; } } } map_data[map->width * map->height] = 0; ggz_conf_write_string(handle, "map", "data", map_data); // Options snprintf(options, sizeof(filename), "%lX", map->options); ggz_conf_write_string(handle, "options", "bin1", options); ggz_conf_commit(handle); return 0; }
void NetProxy::run() { #define SET_ERROR(errno) \ do \ { \ st->_errno = errno; \ epex_detach(_epex, st->_talk->_sock, NULL); \ } while(0) ssize_t ret; netresult_t results[20]; __dlist_t attach_ok_list; __dlist_t attach_fail_list; __dlist_t *ptr; NetStub *st; int sock; int tm_left; int elasp_tm; struct timeval now; _stop = false; while (!_stop) { DLIST_INIT(&attach_ok_list); DLIST_INIT(&attach_fail_list); { AutoLock __lock(_mutex); while (!DLIST_EMPTY(&_attach_list)) { ptr = DLIST_NEXT(&_attach_list); st = GET_OWNER(ptr, NetStub, _att_list); DLIST_REMOVE(ptr); if (epex_attach(_epex, st->_talk->_sock, st, -1)) DLIST_INSERT_B(&st->_tmp_list, &attach_ok_list); else DLIST_INSERT_B(&st->_tmp_list, &attach_fail_list); } } gettimeofday(&now, NULL); while (!DLIST_EMPTY(&attach_fail_list)) { ptr = DLIST_NEXT(&attach_fail_list); st = GET_OWNER(ptr, NetStub, _tmp_list); DLIST_REMOVE(ptr); st->_errno = NET_ERR_ATTACH_FAIL; this->done(st, &now); } while (!DLIST_EMPTY(&attach_ok_list)) { ptr = DLIST_NEXT(&attach_ok_list); st = GET_OWNER(ptr, NetStub, _tmp_list); DLIST_REMOVE(ptr); st->_talk->_req_head._magic_num = MAGIC_NUM; st->_talk->_req_head._body_len = st->_talk->_req_len; st->_status = NET_ST_SEND_HEAD; if (epex_write(_epex, st->_talk->_sock, &st->_talk->_req_head, sizeof(st->_talk->_req_head), NULL, st->_timeout)) { TRACE("try to send head to sock[%d]", st->_talk->_sock); } else { SET_ERROR(NET_ERR_WRITE); } } ret = epex_poll(_epex, results, sizeof(results)/sizeof(results[0])); gettimeofday(&now, NULL); for (long i = 0; i < ret; ++i) { const netresult_t &res = results[i]; st = (NetStub *)res._user_ptr2; if (NET_OP_NOTIFY == res._op_type) { this->done(st, &now); continue; } switch (res._status) { case NET_DONE: break; case NET_ECLOSED: SET_ERROR(NET_ERR_CLOSED); continue; case NET_ETIMEOUT: SET_ERROR(NET_ERR_TIMEOUT); continue; case NET_ERROR: st->_errno = res._errno; /* fall through */ case NET_EDETACHED: continue; default: WARNING("should not be here, res._status=%hd", res._status); continue; } sock = st->_talk->_sock; if (st->_cancel) /* canceled by user */ { TRACE("sock[%d] is canceled by user", sock); epex_detach(_epex, sock, NULL); continue; } elasp_tm = (now.tv_sec - st->_start_tm.tv_sec) * 1000 + (now.tv_usec - st->_start_tm.tv_usec) / 1000; if (st->_timeout < 0) tm_left = -1; else if (st->_timeout > elasp_tm) tm_left = st->_timeout - elasp_tm; else tm_left = 0; switch (st->_status) { case NET_ST_SEND_HEAD: TRACE("send head to sock[%d] ok", sock); st->_tm._send_head = elasp_tm; st->_status = NET_ST_SEND_BODY; if (tm_left == 0) { SET_ERROR(NET_ERR_TIMEOUT); continue; } if (!epex_write(_epex, sock, st->_talk->_req_buf, st->_talk->_req_len, NULL, tm_left)) { SET_ERROR(NET_ERR_WRITE); continue; } TRACE("try to send body[%u] to sock[%d]", st->_talk->_req_len, sock); break; case NET_ST_SEND_BODY: TRACE("send body[%u] to sock[%d] ok", st->_talk->_req_len, sock); st->_tm._send_body = elasp_tm - st->_tm._send_head; st->_status = NET_ST_RECV_HEAD; if (tm_left == 0) { SET_ERROR(NET_ERR_TIMEOUT); continue; } if (!epex_read(_epex, sock, &st->_talk->_res_head, sizeof(st->_talk->_res_head), NULL, tm_left)) { SET_ERROR(NET_ERR_READ); continue; } TRACE("try to recv head from sock[%d]", sock); break; case NET_ST_RECV_HEAD: TRACE("recv head from sock[%d] ok", sock); st->_tm._recv_head = elasp_tm - st->_tm._send_body - st->_tm._send_head; if (st->_talk->_res_head._magic_num != MAGIC_NUM) { SET_ERROR(NET_ERR_MAGIC_NUM); continue; } if (st->_talk->_res_head._body_len > st->_talk->_res_len) { SET_ERROR(NET_ERR_BIG_RESP); continue; } st->_status = NET_ST_RECV_BODY; if (tm_left == 0) { SET_ERROR(NET_ERR_TIMEOUT); continue; } if (!epex_read(_epex, sock, st->_talk->_res_buf, st->_talk->_res_head._body_len, NULL, tm_left)) { SET_ERROR(NET_ERR_READ); continue; } TRACE("try to recv body[%u] from sock[%d]", st->_talk->_res_head._body_len, sock); break; case NET_ST_RECV_BODY: TRACE("recv body[%u] from sock[%d] ok", st->_talk->_res_head._body_len, sock); st->_tm._recv_body = elasp_tm - st->_tm._recv_head - st->_tm._send_body - st->_tm._send_head; st->_status = NET_ST_DONE; epex_detach(_epex, sock, NULL); TRACE("talk with sock[%d] ok", sock); break; default: WARNING("should not be here"); break; } } } NOTICE("NetPoller is stoped now"); #undef SET_ERROR }
int conn_read(struct fd_node_s *_this) { int ret; talk_client_t *cli = (talk_client_t *)_this; conn_t *conn = (conn_t*)_this->context; loop_t *loop = GET_OWNER(cli, loop_t); /* * 每一个watch创建以后,每带有一个超时时间,超时将会调用stop * 超时出现的情况: * 1. * */ if((_this->revent & FD_T_FLAGS) && (conn->stat != CONN_FIN)) { printf("%s => %d\n", __FUNCTION__, __LINE__); if(cli->parm.stop) cli->parm.stop(_this, conn->ctx); conn->stat = CONN_FIN; return 0; } switch(conn->stat) { case CONN_CONNECTING: if(_this->revent & FD_W_FLAGS) { ret = conn_send_req(_this); if(ret < 0) { // printf("%s => %d\n", __FUNCTION__, __LINE__); if(cli->parm.stop) cli->parm.stop(_this, conn->ctx); conn->stat = CONN_FIN; } else { fd_set_mod_node2(loop->_set, _this, FD_R_FLAGS); conn->stat = CONN_WAIT; } } break; case CONN_WAIT: if(_this->revent & FD_R_FLAGS) { ret = conn_recv_rsp(_this); if(ret < 0) { // printf("%s => %d\n", __FUNCTION__, __LINE__); if(cli->parm.stop) cli->parm.stop(_this, conn->ctx); conn->stat = CONN_FIN; } else if(ret == 1) { if(cli->parm.start) cli->parm.start(_this, conn->ctx); //clear buf; _this->in_buf_len = 0; conn->stat = CONN_RW; } } break; case CONN_RW: if(_this->revent & FD_R_FLAGS) { ret = conn_recv_data(_this); if(ret < 0) { printf("%s => %d\n", __FUNCTION__, __LINE__); if(cli->parm.stop) cli->parm.stop(_this, conn->ctx); conn->stat = CONN_FIN; } else if(ret == 1) { if(cli->parm.recv) cli->parm.recv(_this, (HI_TALK_FRMAE_HDR*)_this->in_buf, conn->ctx); //clear buf; _this->in_buf_len = 0; } } break; case CONN_FIN: break; } return 0; }