int32_t _shutdowns_direct( uint8_t index, struct session_manager * manager, struct sidlist * ids ) { uint32_t i = 0; int32_t count = 0; for ( i = 0; i < sidlist_count(ids); ++i ) { sid_t id = sidlist_get(ids, i); if ( SID_INDEX(id) != index ) { continue; } struct session * session = session_manager_get( manager, id ); if ( session == NULL ) { continue; } // 直接终止 ++count; session_close( session ); session_shutdown( session ); } sidlist_destroy( ids ); return count; }
int32_t iolayer_shutdown( iolayer_t self, sid_t id ) { uint8_t index = SID_INDEX(id); struct iolayer * layer = (struct iolayer *)self; if ( index >= layer->nthreads ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index ); return -1; } // 避免在回调函数中直接终止会话 // 这样会引发后续对会话的操作都非法了 #if 0 if ( pthread_self() == iothreads_get_id( layer->group, index ) ) { // 本线程内直接终止 return _shutdown_direct( _get_manager(layer, index), &task ); } #endif // 跨线程提交终止任务 return iothreads_post( layer->group, index, eIOTaskType_Shutdown, (void *)&id, sizeof(id) ); }
int32_t iolayer_set_service( iolayer_t self, sid_t id, ioservice_t * service, void * context ) { // NOT Thread-Safe uint8_t index = SID_INDEX(id); struct iolayer * layer = (struct iolayer *)self; if ( index >= layer->nthreads ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index ); return -1; } struct session_manager * manager = _get_manager( layer, index ); if ( manager == NULL ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's manager[%u] is invalid .", __FUNCTION__, id, index ); return -2; } struct session * session = session_manager_get( manager, id ); if ( session == NULL ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session is invalid .", __FUNCTION__, id ); return -3; } session->context = context; session->service = *service; return 0; }
int32_t iolayer_set_keepalive( iolayer_t self, sid_t id, int32_t seconds ) { // NOT Thread-Safe uint8_t index = SID_INDEX(id); struct iolayer * layer = (struct iolayer *)self; if ( index >= layer->nthreads ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index ); return -1; } struct session_manager * manager = _get_manager( layer, index ); if ( manager == NULL ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's manager[%u] is invalid .", __FUNCTION__, id, index ); return -2; } struct session * session = session_manager_get( manager, id ); if ( session == NULL ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session is invalid .", __FUNCTION__, id ); return -3; } session->setting.keepalive_msecs = seconds*1000; return 0; }
int32_t _broadcast_direct( struct iolayer * self, uint8_t index, struct session_manager * manager, struct message * msg ) { uint32_t i = 0; int32_t count = 0; // 数据改造 if ( self->transform != NULL ) { // 数据需要改造 char * buffer = NULL; uint32_t nbytes = message_get_length( msg ); buffer = self->transform( self->context, message_get_buffer(msg), &nbytes ); if ( buffer == NULL ) { // 数据改造失败 message_destroy( msg ); return -1; } if ( buffer != message_get_buffer(msg) ) { // 数据改造成功 message_set_buffer( msg, buffer, nbytes ); } } for ( i = 0; i < sidlist_count(msg->tolist); ++i ) { sid_t id = sidlist_get(msg->tolist, i); if ( SID_INDEX(id) != index ) { message_add_failure( msg, id ); continue; } struct session * session = session_manager_get( manager, id ); if ( unlikely(session == NULL) ) { message_add_failure( msg, id ); continue; } if ( session_append(session, msg) >= 0 ) { // 尝试单独发送 // 添加到发送队列成功 ++count; } } // 消息发送完毕, 直接销毁 if ( message_is_complete(msg) ) { message_destroy( msg ); } return count; }
int32_t _send_buffer( struct iolayer * self, sid_t id, const char * buf, uint32_t nbytes, int32_t isfree ) { int32_t result = 0; uint8_t index = SID_INDEX(id); if ( unlikely(index >= self->nthreads) ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index ); return -1; } struct task_send task; task.id = id; task.nbytes = nbytes; task.isfree = isfree; task.buf = (char *)buf; if ( pthread_self() == iothreads_get_id( self->group, index ) ) { return _send_direct( self, _get_manager(self, index), &task ); } // 跨线程提交发送任务 if ( isfree == 0 ) { task.buf = (char *)malloc( nbytes ); if ( unlikely( task.buf == NULL ) ) { syslog(LOG_WARNING, "%s(SID=%ld) failed, can't allocate the memory for '_buf' .", __FUNCTION__, id ); return -2; } task.isfree = 1; memcpy( task.buf, buf, nbytes ); } result = iothreads_post( self->group, index, eIOTaskType_Send, (void *)&task, sizeof(task) ); if ( unlikely( result != 0 ) ) { free( task.buf ); } return result; }
int32_t _append_session( struct hashtable * table, struct session * s ) { struct hashnode * node = _find_table( table, s->id, 1 ); if ( unlikely(node == NULL) ) { return -1; } if ( unlikely( node->session != NULL && node->session->id == s->id ) ) { syslog(LOG_WARNING, "%s(Index=%d): the SID (Seq=%u, Sid=%ld) conflict !", __FUNCTION__, (int32_t)SID_INDEX(s->id), (uint32_t)SID_SEQ(s->id), s->id ); return -2; } ++table->count; node->session = s; return 0; }