int ioevent_set(struct fast_task_info *pTask, struct nio_thread_data *pThread, int sock, short event, IOEventCallback callback, const int timeout) { int result; pTask->thread_data = pThread; pTask->event.fd = sock; pTask->event.callback = callback; if (ioevent_attach(&pThread->ev_puller, sock, event, pTask) < 0) { result = errno != 0 ? errno : ENOENT; logError("file: "__FILE__", line: %d, " \ "ioevent_attach fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } pTask->event.timer.data = pTask; pTask->event.timer.expires = g_current_time + timeout; result = fast_timer_add(&pThread->timer, &pTask->event.timer); if (result != 0) { logError("file: "__FILE__", line: %d, " \ "fast_timer_add fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } return 0; }
static void sched_deal_task_queue(ScheduleContext *pContext) { FastDelayTask *task; pthread_mutex_lock(&pContext->delay_queue.lock); if (pContext->delay_queue.head == NULL) { pthread_mutex_unlock(&pContext->delay_queue.lock); return; } task = pContext->delay_queue.head; pContext->delay_queue.head = NULL; pContext->delay_queue.tail = NULL; pthread_mutex_unlock(&pContext->delay_queue.lock); while (task != NULL) { fast_timer_add(&pContext->timer, (FastTimerEntry *)task); task = task->next; } }
static void client_sock_read(int sock, short event, void *arg) { int bytes; int recv_bytes; struct fast_task_info *pTask; StorageClientInfo *pClientInfo; pTask = (struct fast_task_info *)arg; pClientInfo = (StorageClientInfo *)pTask->arg; if (pClientInfo->canceled) { return; } if (pClientInfo->stage != FDFS_STORAGE_STAGE_NIO_RECV) { if (event & IOEVENT_TIMEOUT) { pTask->event.timer.expires = g_current_time + g_fdfs_network_timeout; fast_timer_add(&pTask->thread_data->timer, &pTask->event.timer); } return; } if (event & IOEVENT_TIMEOUT) { if (pClientInfo->total_offset == 0 && pTask->req_count > 0) { pTask->event.timer.expires = g_current_time + g_fdfs_network_timeout; fast_timer_add(&pTask->thread_data->timer, &pTask->event.timer); } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv timeout, " \ "recv offset: %d, expect length: %d", \ __LINE__, pTask->client_ip, \ pTask->offset, pTask->length); task_finish_clean_up(pTask); } return; } if (event & IOEVENT_ERROR) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv error event: %d, " "close connection", __LINE__, pTask->client_ip, event); task_finish_clean_up(pTask); return; } fast_timer_modify(&pTask->thread_data->timer, &pTask->event.timer, g_current_time + g_fdfs_network_timeout); while (1) { if (pClientInfo->total_length == 0) //recv header { recv_bytes = sizeof(TrackerHeader) - pTask->offset; } else { recv_bytes = pTask->length - pTask->offset; } /* logInfo("total_length=%"PRId64", recv_bytes=%d, " "pTask->length=%d, pTask->offset=%d", pClientInfo->total_length, recv_bytes, pTask->length, pTask->offset); */ bytes = recv(sock, pTask->data + pTask->offset, recv_bytes, 0); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { } else if (errno == EINTR) { continue; } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "errno: %d, error info: %s", \ __LINE__, pTask->client_ip, \ errno, STRERROR(errno)); task_finish_clean_up(pTask); } return; } else if (bytes == 0) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "connection disconnected.", \ __LINE__, pTask->client_ip); task_finish_clean_up(pTask); return; } if (pClientInfo->total_length == 0) //header { if (pTask->offset + bytes < sizeof(TrackerHeader)) { pTask->offset += bytes; return; } pClientInfo->total_length=buff2long(((TrackerHeader *) \ pTask->data)->pkg_len); if (pClientInfo->total_length < 0) { logError("file: "__FILE__", line: %d, " \ "client ip: %s, pkg length: " \ "%"PRId64" < 0", \ __LINE__, pTask->client_ip, \ pClientInfo->total_length); task_finish_clean_up(pTask); return; } pClientInfo->total_length += sizeof(TrackerHeader); if (pClientInfo->total_length > pTask->size) { pTask->length = pTask->size; } else { pTask->length = pClientInfo->total_length; } } pTask->offset += bytes; if (pTask->offset >= pTask->length) //recv current pkg done { if (pClientInfo->total_offset + pTask->length >= \ pClientInfo->total_length) { /* current req recv done */ pClientInfo->stage = FDFS_STORAGE_STAGE_NIO_SEND; pTask->req_count++; } if (pClientInfo->total_offset == 0) { pClientInfo->total_offset = pTask->length; storage_deal_task(pTask); } else { pClientInfo->total_offset += pTask->length; /* continue write to file */ storage_dio_queue_push(pTask); } return; } } return; }
static void client_sock_read(int sock, short event, void *arg) { int bytes; int recv_bytes; struct fast_task_info *pTask; pTask = (struct fast_task_info *)arg; if (event & IOEVENT_TIMEOUT) { if (pTask->offset == 0 && pTask->req_count > 0) { pTask->event.timer.expires = g_current_time + g_fdfs_network_timeout; fast_timer_add(&pTask->thread_data->timer, &pTask->event.timer); } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv timeout, " \ "recv offset: %d, expect length: %d", \ __LINE__, pTask->client_ip, \ pTask->offset, pTask->length); task_finish_clean_up(pTask); } return; } if (event & IOEVENT_ERROR) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv error event: %d, " "close connection", __LINE__, pTask->client_ip, event); task_finish_clean_up(pTask); return; } while (1) { fast_timer_modify(&pTask->thread_data->timer, &pTask->event.timer, g_current_time + g_fdfs_network_timeout); if (pTask->length == 0) //recv header { recv_bytes = sizeof(TrackerHeader) - pTask->offset; } else { recv_bytes = pTask->length - pTask->offset; } bytes = recv(sock, pTask->data + pTask->offset, recv_bytes, 0); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { } else if (errno == EINTR) { continue; } else { logError("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "errno: %d, error info: %s", \ __LINE__, pTask->client_ip, \ errno, STRERROR(errno)); task_finish_clean_up(pTask); } return; } else if (bytes == 0) { logDebug("file: "__FILE__", line: %d, " \ "client ip: %s, recv failed, " \ "connection disconnected.", \ __LINE__, pTask->client_ip); task_finish_clean_up(pTask); return; } if (pTask->length == 0) //header { if (pTask->offset + bytes < sizeof(TrackerHeader)) { pTask->offset += bytes; return; } pTask->length = buff2long(((TrackerHeader *) \ pTask->data)->pkg_len); if (pTask->length < 0) { logError("file: "__FILE__", line: %d, " \ "client ip: %s, pkg length: %d < 0", \ __LINE__, pTask->client_ip, \ pTask->length); task_finish_clean_up(pTask); return; } pTask->length += sizeof(TrackerHeader); if (pTask->length > TRACKER_MAX_PACKAGE_SIZE) { logError("file: "__FILE__", line: %d, " \ "client ip: %s, pkg length: %d > " \ "max pkg size: %d", __LINE__, \ pTask->client_ip, pTask->length, \ TRACKER_MAX_PACKAGE_SIZE); task_finish_clean_up(pTask); return; } } pTask->offset += bytes; if (pTask->offset >= pTask->length) //recv done { pTask->req_count++; tracker_deal_task(pTask); return; } } return; }