static int swClient_tcp_sendfile_sync(swClient *cli, char *filename) { if (swSocket_sendfile_sync(cli->connection.fd, filename, cli->timeout) < 0) { SwooleG.error = errno; return SW_ERR; } return SW_OK; }
static int swClient_tcp_sendfile_sync(swClient *cli, char *filename, off_t offset, size_t length) { if (swSocket_sendfile_sync(cli->socket->fd, filename, offset, length, cli->timeout) < 0) { SwooleG.error = errno; return SW_ERR; } return SW_OK; }
/** * Use message queue ipc */ int swFactoryProcess_writer_loop_queue(swThreadParam *param) { swEventData *resp; swServer *serv = SwooleG.serv; int pti = param->pti; swQueue_data sdata; //必须加1,msg_type必须不能为0 sdata.mtype = pti + 1; swSignal_none(); while (SwooleG.running > 0) { swTrace("[Writer]wt_queue[%ld]->out wait", sdata.mtype); if (serv->write_queue.out(&serv->write_queue, &sdata, sizeof(sdata.mdata)) < 0) { if (errno == EINTR) { continue; } swWarn("[writer]wt_queue->out fail.Error: %s [%d]", strerror(errno), errno); } else { int ret; resp = (swEventData *) sdata.mdata; //Close //TODO: thread safe, should close in reactor thread. if (resp->info.len == 0) { close_fd: swServer_connection_close(SwooleG.serv, resp->info.fd, 0); continue; } else { if (resp->info.type == SW_EVENT_SENDFILE) { ret = swSocket_sendfile_sync(resp->info.fd, resp->data, SW_WRITER_TIMEOUT); } else { ret = swConnection_send_blocking(resp->info.fd, resp->data, resp->info.len, 1000 * SW_WRITER_TIMEOUT); } if (ret < 0) { switch (swConnection_error(errno)) { case SW_ERROR: swWarn("send to fd[%d] failed. Error: %s[%d]", resp->info.fd, strerror(errno), errno); break; case SW_CLOSE: goto close_fd; default: break; } } } } } pthread_exit((void *) param); return SW_OK; }