Init Repo

This commit is contained in:
root
2019-09-06 23:53:10 +08:00
commit f0ef89dfbb
7905 changed files with 914138 additions and 0 deletions

170
vendor/swoole/src/factory/Factory.c vendored Executable file
View File

@ -0,0 +1,170 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#include "swoole.h"
#include "Server.h"
int swFactory_create(swFactory *factory)
{
factory->dispatch = swFactory_dispatch;
factory->finish = swFactory_finish;
factory->start = swFactory_start;
factory->shutdown = swFactory_shutdown;
factory->end = swFactory_end;
factory->notify = swFactory_notify;
return SW_OK;
}
int swFactory_start(swFactory *factory)
{
SwooleWG.run_always = 1;
return SW_OK;
}
int swFactory_shutdown(swFactory *factory)
{
return SW_OK;
}
int swFactory_dispatch(swFactory *factory, swDispatchData *task)
{
swServer *serv = factory->ptr;
factory->last_from_id = task->data.info.from_id;
if (swEventData_is_stream(task->data.info.type))
{
swConnection *conn = swServer_connection_get(serv, task->data.info.fd);
if (conn == NULL || conn->active == 0)
{
swWarn("dispatch[type=%d] failed, connection#%d is not active.", task->data.info.type, task->data.info.fd);
return SW_ERR;
}
//server active close, discard data.
if (conn->closed)
{
swWarn("dispatch[type=%d] failed, connection#%d is closed by server.", task->data.info.type,
task->data.info.fd);
return SW_OK;
}
//converted fd to session_id
task->data.info.fd = conn->session_id;
task->data.info.from_fd = conn->from_fd;
}
return swWorker_onTask(factory, &task->data);
}
int swFactory_notify(swFactory *factory, swDataHead *info)
{
swServer *serv = factory->ptr;
swConnection *conn = swServer_connection_get(serv, info->fd);
if (conn == NULL || conn->active == 0)
{
swWarn("dispatch[type=%d] failed, connection#%d is not active.", info->type, info->fd);
return SW_ERR;
}
//server active close, discard data.
if (conn->closed)
{
swWarn("dispatch[type=%d] failed, connection#%d is closed by server.", info->type, info->fd);
return SW_OK;
}
//converted fd to session_id
info->fd = conn->session_id;
info->from_fd = conn->from_fd;
return swWorker_onTask(factory, (swEventData *) info);
}
int swFactory_end(swFactory *factory, int fd)
{
swServer *serv = factory->ptr;
swSendData _send;
swDataHead info;
bzero(&_send, sizeof(_send));
_send.info.fd = fd;
_send.info.len = 0;
_send.info.type = SW_EVENT_CLOSE;
swConnection *conn = swWorker_get_connection(serv, fd);
if (conn == NULL || conn->active == 0)
{
//swWarn("can not close. Connection[%d] not found.", _send.info.fd);
return SW_ERR;
}
else if (conn->close_force)
{
goto do_close;
}
else if (conn->closing)
{
swWarn("The connection[%d] is closing.", fd);
return SW_ERR;
}
else if (conn->closed)
{
return SW_ERR;
}
else
{
do_close:
conn->closing = 1;
if (serv->onClose != NULL)
{
info.fd = fd;
if (conn->close_actively)
{
info.from_id = -1;
}
else
{
info.from_id = conn->from_id;
}
info.from_fd = conn->from_fd;
serv->onClose(serv, &info);
}
conn->closing = 0;
conn->closed = 1;
conn->close_errno = 0;
if (swBuffer_empty(conn->out_buffer) || conn->removed)
{
swReactor *reactor = &serv->reactor_threads[SwooleTG.id].reactor;
return swReactorThread_close(reactor, conn->fd);
}
else
{
swBuffer_trunk *trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_CLOSE, 0);
trunk->store.data.val1 = _send.info.type;
return SW_OK;
}
}
}
int swFactory_finish(swFactory *factory, swSendData *resp)
{
if (resp->length == 0)
{
resp->length = resp->info.len;
}
if (swReactorThread_send(resp) < 0)
{
return SW_ERR;
}
else
{
return SW_OK;
}
}

335
vendor/swoole/src/factory/FactoryProcess.c vendored Executable file
View File

@ -0,0 +1,335 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#include "swoole.h"
#include "Server.h"
#include <signal.h>
#include <sys/time.h>
static int swFactoryProcess_start(swFactory *factory);
static int swFactoryProcess_notify(swFactory *factory, swDataHead *event);
static int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *buf);
static int swFactoryProcess_finish(swFactory *factory, swSendData *data);
static int swFactoryProcess_shutdown(swFactory *factory);
static int swFactoryProcess_end(swFactory *factory, int fd);
int swFactoryProcess_create(swFactory *factory, int worker_num)
{
swFactoryProcess *object;
object = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swFactoryProcess));
if (object == NULL)
{
swWarn("[Master] malloc[object] failed");
return SW_ERR;
}
factory->object = object;
factory->dispatch = swFactoryProcess_dispatch;
factory->finish = swFactoryProcess_finish;
factory->start = swFactoryProcess_start;
factory->notify = swFactoryProcess_notify;
factory->shutdown = swFactoryProcess_shutdown;
factory->end = swFactoryProcess_end;
return SW_OK;
}
static int swFactoryProcess_shutdown(swFactory *factory)
{
int status;
swServer *serv = factory->ptr;
if (swKill(serv->gs->manager_pid, SIGTERM) < 0)
{
swSysError("kill(%d) failed.", serv->gs->manager_pid);
}
if (swWaitpid(serv->gs->manager_pid, &status, 0) < 0)
{
swSysError("waitpid(%d) failed.", serv->gs->manager_pid);
}
return SW_OK;
}
static int swFactoryProcess_start(swFactory *factory)
{
int i;
swServer *serv = factory->ptr;
swWorker *worker;
for (i = 0; i < serv->worker_num; i++)
{
worker = swServer_get_worker(serv, i);
if (swWorker_create(worker) < 0)
{
return SW_ERR;
}
}
serv->reactor_pipe_num = serv->worker_num / serv->reactor_num;
//必须先启动manager进程组,否则会带线程fork
if (swManager_start(factory) < 0)
{
swWarn("swFactoryProcess_manager_start failed.");
return SW_ERR;
}
//主进程需要设置为直写模式
factory->finish = swFactory_finish;
return SW_OK;
}
static __thread struct
{
long target_worker_id;
swDataHead _send;
} sw_notify_data;
/**
* [ReactorThread] notify info to worker process
*/
static int swFactoryProcess_notify(swFactory *factory, swDataHead *ev)
{
memcpy(&sw_notify_data._send, ev, sizeof(swDataHead));
sw_notify_data._send.len = 0;
sw_notify_data.target_worker_id = -1;
return factory->dispatch(factory, (swDispatchData *) &sw_notify_data);
}
/**
* [ReactorThread] dispatch request to worker
*/
static int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *task)
{
uint32_t send_len = sizeof(task->data.info) + task->data.info.len;
int target_worker_id;
swServer *serv = SwooleG.serv;
int fd = task->data.info.fd;
if (task->target_worker_id < 0)
{
#ifndef SW_USE_RINGBUFFER
if (SwooleTG.factory_lock_target)
{
if (SwooleTG.factory_target_worker < 0)
{
target_worker_id = swServer_worker_schedule(serv, fd, &task->data);
SwooleTG.factory_target_worker = target_worker_id;
}
else
{
target_worker_id = SwooleTG.factory_target_worker;
}
}
else
#endif
{
target_worker_id = swServer_worker_schedule(serv, fd, &task->data);
}
}
else
{
target_worker_id = task->target_worker_id;
}
//discard the data packet.
if (target_worker_id < 0)
{
return SW_OK;
}
if (swEventData_is_stream(task->data.info.type))
{
swConnection *conn = swServer_connection_get(serv, fd);
if (conn == NULL || conn->active == 0)
{
swWarn("dispatch[type=%d] failed, connection#%d is not active.", task->data.info.type, fd);
return SW_ERR;
}
//server active close, discard data.
if (conn->closed)
{
//Connection has been clsoed by server
if (!(task->data.info.type == SW_EVENT_CLOSE && conn->close_force))
{
return SW_OK;
}
}
//converted fd to session_id
task->data.info.fd = conn->session_id;
task->data.info.from_fd = conn->from_fd;
}
return swReactorThread_send2worker((void *) &(task->data), send_len, target_worker_id);
}
/**
* worker: send to client
*/
static int swFactoryProcess_finish(swFactory *factory, swSendData *resp)
{
int ret, sendn;
swServer *serv = factory->ptr;
int session_id = resp->info.fd;
swConnection *conn;
if (resp->info.type != SW_EVENT_CLOSE)
{
conn = swServer_connection_verify(serv, session_id);
}
else
{
conn = swServer_connection_verify_no_ssl(serv, session_id);
}
if (!conn)
{
swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "connection[fd=%d] does not exists.", session_id);
return SW_ERR;
}
else if ((conn->closed || conn->removed) && resp->info.type != SW_EVENT_CLOSE)
{
int _len = resp->length > 0 ? resp->length : resp->info.len;
swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "send %d byte failed, because connection[fd=%d] is closed.", _len, session_id);
return SW_ERR;
}
else if (conn->overflow)
{
swoole_error_log(SW_LOG_WARNING, SW_ERROR_OUTPUT_BUFFER_OVERFLOW, "send failed, connection[fd=%d] output buffer has been overflowed.", session_id);
return SW_ERR;
}
swEventData ev_data;
ev_data.info.fd = session_id;
ev_data.info.type = resp->info.type;
swWorker *worker = swServer_get_worker(serv, SwooleWG.id);
/**
* Big response, use shared memory
*/
if (resp->length > 0)
{
if (worker == NULL || worker->send_shm == NULL)
{
goto pack_data;
}
//worker process
if (SwooleG.main_reactor)
{
int _pipe_fd = swWorker_get_send_pipe(serv, session_id, conn->from_id);
swConnection *_pipe_socket = swReactor_get(SwooleG.main_reactor, _pipe_fd);
//cannot use send_shm
if (!swBuffer_empty(_pipe_socket->out_buffer))
{
pack_data:
if (swTaskWorker_large_pack(&ev_data, resp->data, resp->length) < 0)
{
return SW_ERR;
}
ev_data.info.from_fd = SW_RESPONSE_TMPFILE;
goto send_to_reactor_thread;
}
}
swPackage_response response;
response.length = resp->length;
response.worker_id = SwooleWG.id;
ev_data.info.from_fd = SW_RESPONSE_SHM;
ev_data.info.len = sizeof(response);
memcpy(ev_data.data, &response, sizeof(response));
swTrace("[Worker] big response, length=%d|worker_id=%d", response.length, response.worker_id);
worker->lock.lock(&worker->lock);
memcpy(worker->send_shm, resp->data, resp->length);
}
else
{
//copy data
memcpy(ev_data.data, resp->data, resp->info.len);
ev_data.info.len = resp->info.len;
ev_data.info.from_fd = SW_RESPONSE_SMALL;
}
send_to_reactor_thread: ev_data.info.from_id = conn->from_id;
sendn = ev_data.info.len + sizeof(resp->info);
swTrace("[Worker] send: sendn=%d|type=%d|content=%s", sendn, resp->info.type, resp->data);
ret = swWorker_send2reactor(&ev_data, sendn, session_id);
if (ret < 0)
{
swWarn("sendto to reactor failed. Error: %s [%d]", strerror(errno), errno);
}
return ret;
}
static int swFactoryProcess_end(swFactory *factory, int fd)
{
swServer *serv = factory->ptr;
swSendData _send;
swDataHead info;
bzero(&_send, sizeof(_send));
_send.info.fd = fd;
_send.info.len = 0;
_send.info.type = SW_EVENT_CLOSE;
swConnection *conn = swWorker_get_connection(serv, fd);
if (conn == NULL || conn->active == 0)
{
SwooleG.error = SW_ERROR_SESSION_NOT_EXIST;
return SW_ERR;
}
else if (conn->close_force)
{
goto do_close;
}
else if (conn->closing)
{
swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSING, "The connection[%d] is closing.", fd);
return SW_ERR;
}
else if (conn->closed)
{
return SW_ERR;
}
else
{
do_close:
conn->closing = 1;
if (serv->onClose != NULL)
{
info.fd = fd;
if (conn->close_actively)
{
info.from_id = -1;
}
else
{
info.from_id = conn->from_id;
}
info.from_fd = conn->from_fd;
serv->onClose(serv, &info);
}
conn->closing = 0;
conn->closed = 1;
conn->close_errno = 0;
return factory->finish(factory, &_send);
}
}

245
vendor/swoole/src/factory/FactoryThread.c vendored Executable file
View File

@ -0,0 +1,245 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#include "swoole.h"
#include "Server.h"
static int swFactoryThread_dispatch(swFactory *factory, swDispatchData *buf);
static int swFactoryThread_finish(swFactory *factory, swSendData *data);
static int swFactoryThread_shutdown(swFactory *factory);
static int swFactoryThread_start(swFactory *factory);
typedef struct _swWorkerThread
{
pthread_t ptid; //线程ID
int pipe_num; //writer thread's pipe num
int *pipes; //worker pipes
int c_pipe; //current pipe
swReactor reactor;
swShareMemory shm; //共享内存
swPipe evfd; //eventfd
} swWorkerThread;
typedef struct _swFactoryThread
{
int worker_num;
swThreadPool workers;
} swFactoryThread;
static int swFactoryThread_onTask(swThreadPool *pool, void *data, int len);
static void swFactoryThread_onStart(swThreadPool *pool, int id);
static void swFactoryThread_onStop(swThreadPool *pool, int id);
int swFactoryThread_create(swFactory *factory, int worker_num)
{
swFactoryThread *object;
swServer *serv = factory->ptr;
object = sw_calloc(worker_num, sizeof(swFactoryThread));
if (object == NULL)
{
swWarn("malloc[0] failed");
return SW_ERR;
}
if (swThreadPool_create(&object->workers, worker_num) < 0)
{
sw_free(object);
return SW_ERR;
}
int i;
swReactorThread *thread;
for (i = 0; i < serv->reactor_num; i++)
{
thread = swServer_get_thread(serv, i);
swMutex_create(&thread->lock, 0);
}
object->worker_num = worker_num;
factory->object = object;
factory->dispatch = swFactoryThread_dispatch;
factory->finish = swFactoryThread_finish;
factory->end = swFactory_end;
factory->start = swFactoryThread_start;
factory->shutdown = swFactoryThread_shutdown;
factory->notify = swFactory_notify;
object->workers.onStart = swFactoryThread_onStart;
object->workers.onStop = swFactoryThread_onStop;
object->workers.onTask = swFactoryThread_onTask;
object->workers.ptr1 = factory->ptr;
object->workers.ptr2 = factory;
return SW_OK;
}
static int swFactoryThread_start(swFactory *factory)
{
swFactoryThread *object = factory->object;
SwooleWG.run_always = 1;
swThreadPool_run(&object->workers);
return SW_OK;
}
static int swFactoryThread_shutdown(swFactory *factory)
{
SwooleG.running = 0;
swFactoryThread *object = factory->object;
swThreadPool_free(&object->workers);
sw_free(object);
return SW_OK;
}
static int swFactoryThread_finish(swFactory *factory, swSendData *_send)
{
swServer *serv = SwooleG.serv;
uint32_t session_id = _send->info.fd;
if (_send->length == 0)
{
_send->length = _send->info.len;
}
swConnection *conn = swServer_connection_verify(serv, session_id);
if (!conn)
{
if (_send->info.type == SW_EVENT_TCP)
{
swWarn("send %d byte failed, session#%d is closed.", _send->length, session_id);
}
else
{
swWarn("send [%d] failed, session#%d is closed.", _send->info.type, session_id);
}
return SW_ERR;
}
return swSocket_write_blocking(conn->fd, _send->data, _send->length);
}
/**
* 写线程模式
*/
int swFactoryThread_dispatch(swFactory *factory, swDispatchData *task)
{
swServer *serv = SwooleG.serv;
swFactoryThread *object = factory->object;
if (swEventData_is_stream(task->data.info.type))
{
swConnection *conn = swServer_connection_get(serv, task->data.info.fd);
if (conn == NULL || conn->active == 0)
{
swWarn("dispatch[type=%d] failed, connection#%d is not active.", task->data.info.type, task->data.info.fd);
return SW_ERR;
}
//server active close, discard data.
if (conn->closed)
{
swWarn("dispatch[type=%d] failed, connection#%d is closed by server.", task->data.info.type,
task->data.info.fd);
return SW_OK;
}
//converted fd to session_id
task->data.info.fd = conn->session_id;
task->data.info.from_fd = conn->from_fd;
}
int mem_size = sizeof(swDataHead) + task->data.info.len + 1;
char *data = sw_malloc(mem_size);
if (data == NULL)
{
swWarn("malloc failed");
return SW_ERR;
}
memcpy(data, &(task->data), mem_size);
data[sizeof(swDataHead) + task->data.info.len] = 0;
if (swThreadPool_dispatch(&object->workers, (void *) data, 0) < 0)
{
swWarn("RingQueue is full");
return SW_ERR;
}
else
{
return SW_OK;
}
}
static void swFactoryThread_onStart(swThreadPool *pool, int id)
{
swServer *serv = pool->ptr1;
if (serv->onWorkerStart != NULL)
{
serv->onWorkerStart(serv, id);
}
swSignal_none();
SwooleTG.id = serv->reactor_num + id;
SwooleTG.type = SW_THREAD_WORKER;
SwooleTG.buffer_input = swServer_create_worker_buffer(serv);
if (!SwooleTG.buffer_input)
{
return;
}
//cpu affinity setting
#ifdef HAVE_CPU_AFFINITY
if (serv->open_cpu_affinity)
{
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
if (serv->cpu_affinity_available_num)
{
CPU_SET(serv->cpu_affinity_available[id % serv->cpu_affinity_available_num], &cpu_set);
}
else
{
CPU_SET(id % SW_CPU_NUM, &cpu_set);
}
if (0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set))
{
swWarn("pthread_setaffinity_np() failed");
}
}
#endif
}
static void swFactoryThread_onStop(swThreadPool *pool, int id)
{
swServer *serv = SwooleG.serv;
if (serv->onWorkerStop != NULL)
{
serv->onWorkerStop(serv, id);
}
}
static int swFactoryThread_onTask(swThreadPool *pool, void *data, int len)
{
swFactory *factory = pool->ptr2;
int ret = swWorker_onTask(factory, (swEventData*) data);
sw_free(data);
return ret;
}