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_write(int sock, short event, void *arg) { int bytes; struct fast_task_info *pTask; StorageClientInfo *pClientInfo; pTask = (struct fast_task_info *)arg; pClientInfo = (StorageClientInfo *)pTask->arg; if (pClientInfo->canceled) { return; } if (event & IOEVENT_TIMEOUT) { logError("file: "__FILE__", line: %d, " \ "send timeout", __LINE__); 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); bytes = send(sock, pTask->data + pTask->offset, \ pTask->length - pTask->offset, 0); //printf("%08X sended %d bytes\n", (int)pTask, bytes); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { set_send_event(pTask); } 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) { logWarning("file: "__FILE__", line: %d, " \ "send failed, connection disconnected.", \ __LINE__); task_finish_clean_up(pTask); return; } pTask->offset += bytes; if (pTask->offset >= pTask->length) { if (set_recv_event(pTask) != 0) { return; } pClientInfo->total_offset += pTask->length; if (pClientInfo->total_offset>=pClientInfo->total_length) { if (pClientInfo->total_length == sizeof(TrackerHeader) && ((TrackerHeader *)pTask->data)->status == EINVAL) { logDebug("file: "__FILE__", line: %d, "\ "close conn: #%d, client ip: %s", \ __LINE__, pTask->event.fd, pTask->client_ip); task_finish_clean_up(pTask); return; } /* reponse done, try to recv again */ pClientInfo->total_length = 0; pClientInfo->total_offset = 0; pTask->offset = 0; pTask->length = 0; pClientInfo->stage = FDFS_STORAGE_STAGE_NIO_RECV; } else //continue to send file content { pTask->length = 0; /* continue read from file */ storage_dio_queue_push(pTask); } return; } } }
static void client_sock_write(int sock, short event, void *arg) { int bytes; int result; struct fast_task_info *pTask; StorageClientInfo *pClientInfo; pTask = (struct fast_task_info *)arg; if (event == EV_TIMEOUT) { logError("file: "__FILE__", line: %d, " \ "send timeout", __LINE__); task_finish_clean_up(pTask); return; } pClientInfo = (StorageClientInfo *)pTask->arg; while (1) { bytes = send(sock, pTask->data + pTask->offset, \ pTask->length - pTask->offset, 0); //printf("%08X sended %d bytes\n", (int)pTask, bytes); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { if (event_add(&pTask->ev_write, &g_network_tv) != 0) { task_finish_clean_up(pTask); logError("file: "__FILE__", line: %d, " \ "event_add fail.", __LINE__); } } 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) { logWarning("file: "__FILE__", line: %d, " \ "send failed, connection disconnected.", \ __LINE__); task_finish_clean_up(pTask); return; } pTask->offset += bytes; if (pTask->offset >= pTask->length) { pClientInfo->total_offset += pTask->length; if (pClientInfo->total_offset>=pClientInfo->total_length) { /* reponse done, try to recv again */ pClientInfo->total_length = 0; pClientInfo->total_offset = 0; pTask->offset = 0; pTask->length = 0; pClientInfo->stage = FDFS_STORAGE_STAGE_NIO_RECV; if ((result=event_add(&pTask->ev_read, \ &g_network_tv)) != 0) { task_finish_clean_up(pTask); logError("file: "__FILE__", line: %d, "\ "event_add fail.", __LINE__); return; } } else //continue to send file content { pTask->length = 0; /* continue read from file */ storage_dio_queue_push(pTask); } return; } } }