10Sigor@sysoev.ru
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru */
60Sigor@sysoev.ru
70Sigor@sysoev.ru #include <nxt_main.h>
80Sigor@sysoev.ru
90Sigor@sysoev.ru
101Sigor@sysoev.ru static void nxt_job_thread_trampoline(nxt_task_t *task, void *obj, void *data);
111Sigor@sysoev.ru static void nxt_job_thread_return_handler(nxt_task_t *task, void *obj,
120Sigor@sysoev.ru void *data);
130Sigor@sysoev.ru
140Sigor@sysoev.ru
150Sigor@sysoev.ru void *
nxt_job_create(nxt_mp_t * mp,size_t size)1665Sigor@sysoev.ru nxt_job_create(nxt_mp_t *mp, size_t size)
170Sigor@sysoev.ru {
180Sigor@sysoev.ru size_t cache_size;
190Sigor@sysoev.ru nxt_job_t *job;
200Sigor@sysoev.ru
210Sigor@sysoev.ru if (mp == NULL) {
2265Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32);
230Sigor@sysoev.ru if (nxt_slow_path(mp == NULL)) {
240Sigor@sysoev.ru return NULL;
250Sigor@sysoev.ru }
260Sigor@sysoev.ru
2765Sigor@sysoev.ru job = nxt_mp_zget(mp, size);
280Sigor@sysoev.ru cache_size = 0;
290Sigor@sysoev.ru
300Sigor@sysoev.ru } else {
3165Sigor@sysoev.ru job = nxt_mp_zalloc(mp, size);
320Sigor@sysoev.ru cache_size = size;
330Sigor@sysoev.ru }
340Sigor@sysoev.ru
35*2403Sa.clayton@nginx.com if (nxt_slow_path(job == NULL)) {
36*2403Sa.clayton@nginx.com return NULL;
370Sigor@sysoev.ru }
380Sigor@sysoev.ru
39*2403Sa.clayton@nginx.com job->cache_size = (uint16_t) cache_size;
40*2403Sa.clayton@nginx.com job->mem_pool = mp;
41*2403Sa.clayton@nginx.com nxt_job_set_name(job, "job");
42*2403Sa.clayton@nginx.com
430Sigor@sysoev.ru /* Allow safe nxt_queue_remove() in nxt_job_destroy(). */
440Sigor@sysoev.ru nxt_queue_self(&job->link);
450Sigor@sysoev.ru
460Sigor@sysoev.ru return job;
470Sigor@sysoev.ru }
480Sigor@sysoev.ru
490Sigor@sysoev.ru
500Sigor@sysoev.ru void
nxt_job_init(nxt_job_t * job,size_t size)510Sigor@sysoev.ru nxt_job_init(nxt_job_t *job, size_t size)
520Sigor@sysoev.ru {
530Sigor@sysoev.ru nxt_memzero(job, size);
540Sigor@sysoev.ru
550Sigor@sysoev.ru nxt_job_set_name(job, "job");
560Sigor@sysoev.ru
570Sigor@sysoev.ru nxt_queue_self(&job->link);
580Sigor@sysoev.ru }
590Sigor@sysoev.ru
600Sigor@sysoev.ru
610Sigor@sysoev.ru void
nxt_job_destroy(nxt_task_t * task,void * data)6220Sigor@sysoev.ru nxt_job_destroy(nxt_task_t *task, void *data)
630Sigor@sysoev.ru {
640Sigor@sysoev.ru nxt_job_t *job;
650Sigor@sysoev.ru
660Sigor@sysoev.ru job = data;
670Sigor@sysoev.ru
680Sigor@sysoev.ru nxt_queue_remove(&job->link);
690Sigor@sysoev.ru
700Sigor@sysoev.ru if (job->cache_size == 0) {
710Sigor@sysoev.ru
720Sigor@sysoev.ru if (job->mem_pool != NULL) {
7365Sigor@sysoev.ru nxt_mp_destroy(job->mem_pool);
740Sigor@sysoev.ru }
750Sigor@sysoev.ru
760Sigor@sysoev.ru } else {
7765Sigor@sysoev.ru nxt_mp_free(job->mem_pool, job);
780Sigor@sysoev.ru }
790Sigor@sysoev.ru }
800Sigor@sysoev.ru
810Sigor@sysoev.ru
8265Sigor@sysoev.ru #if 0
8365Sigor@sysoev.ru
840Sigor@sysoev.ru nxt_int_t
8565Sigor@sysoev.ru nxt_job_cleanup_add(nxt_mp_t *mp, nxt_job_t *job)
860Sigor@sysoev.ru {
870Sigor@sysoev.ru nxt_mem_pool_cleanup_t *mpcl;
880Sigor@sysoev.ru
890Sigor@sysoev.ru mpcl = nxt_mem_pool_cleanup(mp, 0);
900Sigor@sysoev.ru
910Sigor@sysoev.ru if (nxt_fast_path(mpcl != NULL)) {
920Sigor@sysoev.ru mpcl->handler = nxt_job_destroy;
930Sigor@sysoev.ru mpcl->data = job;
940Sigor@sysoev.ru return NXT_OK;
950Sigor@sysoev.ru }
960Sigor@sysoev.ru
970Sigor@sysoev.ru return NXT_ERROR;
980Sigor@sysoev.ru }
990Sigor@sysoev.ru
10065Sigor@sysoev.ru #endif
10165Sigor@sysoev.ru
1020Sigor@sysoev.ru
1030Sigor@sysoev.ru /*
1040Sigor@sysoev.ru * The (void *) casts in nxt_thread_pool_post() and nxt_event_engine_post()
1050Sigor@sysoev.ru * calls and to the "nxt_work_handler_t" are required by Sun C.
1060Sigor@sysoev.ru */
1070Sigor@sysoev.ru
1080Sigor@sysoev.ru void
nxt_job_start(nxt_task_t * task,nxt_job_t * job,nxt_work_handler_t handler)1091Sigor@sysoev.ru nxt_job_start(nxt_task_t *task, nxt_job_t *job, nxt_work_handler_t handler)
1100Sigor@sysoev.ru {
1111Sigor@sysoev.ru nxt_debug(task, "%s start", job->name);
1120Sigor@sysoev.ru
1130Sigor@sysoev.ru if (job->thread_pool != NULL) {
1140Sigor@sysoev.ru nxt_int_t ret;
1150Sigor@sysoev.ru
1161Sigor@sysoev.ru job->engine = task->thread->engine;
1171Sigor@sysoev.ru
1184Sigor@sysoev.ru nxt_work_set(&job->work, nxt_job_thread_trampoline,
1194Sigor@sysoev.ru job->task, job, (void *) handler);
1204Sigor@sysoev.ru
1214Sigor@sysoev.ru ret = nxt_thread_pool_post(job->thread_pool, &job->work);
1224Sigor@sysoev.ru
1230Sigor@sysoev.ru if (ret == NXT_OK) {
1240Sigor@sysoev.ru return;
1250Sigor@sysoev.ru }
1260Sigor@sysoev.ru
1270Sigor@sysoev.ru handler = job->abort_handler;
1280Sigor@sysoev.ru }
1290Sigor@sysoev.ru
1304Sigor@sysoev.ru handler(job->task, job, job->data);
1310Sigor@sysoev.ru }
1320Sigor@sysoev.ru
1330Sigor@sysoev.ru
1340Sigor@sysoev.ru /* A trampoline function is called by a thread pool thread. */
1350Sigor@sysoev.ru
1360Sigor@sysoev.ru static void
nxt_job_thread_trampoline(nxt_task_t * task,void * obj,void * data)1371Sigor@sysoev.ru nxt_job_thread_trampoline(nxt_task_t *task, void *obj, void *data)
1380Sigor@sysoev.ru {
1390Sigor@sysoev.ru nxt_job_t *job;
1400Sigor@sysoev.ru nxt_work_handler_t handler;
1410Sigor@sysoev.ru
1420Sigor@sysoev.ru job = obj;
1430Sigor@sysoev.ru handler = (nxt_work_handler_t) data;
1440Sigor@sysoev.ru
1451Sigor@sysoev.ru nxt_debug(task, "%s thread", job->name);
1460Sigor@sysoev.ru
1470Sigor@sysoev.ru if (nxt_slow_path(job->cancel)) {
1481Sigor@sysoev.ru nxt_job_return(task, job, job->abort_handler);
1490Sigor@sysoev.ru
1500Sigor@sysoev.ru } else {
1514Sigor@sysoev.ru handler(job->task, job, job->data);
1520Sigor@sysoev.ru }
1530Sigor@sysoev.ru }
1540Sigor@sysoev.ru
1550Sigor@sysoev.ru
1560Sigor@sysoev.ru void
nxt_job_return(nxt_task_t * task,nxt_job_t * job,nxt_work_handler_t handler)1571Sigor@sysoev.ru nxt_job_return(nxt_task_t *task, nxt_job_t *job, nxt_work_handler_t handler)
1580Sigor@sysoev.ru {
1591Sigor@sysoev.ru nxt_debug(task, "%s return", job->name);
1600Sigor@sysoev.ru
1610Sigor@sysoev.ru if (job->engine != NULL) {
1620Sigor@sysoev.ru /* A return function is called in thread pool thread context. */
1634Sigor@sysoev.ru
1644Sigor@sysoev.ru nxt_work_set(&job->work, nxt_job_thread_return_handler,
1654Sigor@sysoev.ru job->task, job, (void *) handler);
1664Sigor@sysoev.ru
1674Sigor@sysoev.ru nxt_event_engine_post(job->engine, &job->work);
1684Sigor@sysoev.ru
1690Sigor@sysoev.ru return;
1700Sigor@sysoev.ru }
1710Sigor@sysoev.ru
1720Sigor@sysoev.ru if (nxt_slow_path(job->cancel)) {
1731Sigor@sysoev.ru nxt_debug(task, "%s cancellation", job->name);
1740Sigor@sysoev.ru handler = job->abort_handler;
1750Sigor@sysoev.ru }
1760Sigor@sysoev.ru
1774Sigor@sysoev.ru nxt_work_queue_add(&task->thread->engine->fast_work_queue,
1784Sigor@sysoev.ru handler, job->task, job, job->data);
1790Sigor@sysoev.ru }
1800Sigor@sysoev.ru
1810Sigor@sysoev.ru
1820Sigor@sysoev.ru static void
nxt_job_thread_return_handler(nxt_task_t * task,void * obj,void * data)1831Sigor@sysoev.ru nxt_job_thread_return_handler(nxt_task_t *task, void *obj, void *data)
1840Sigor@sysoev.ru {
1850Sigor@sysoev.ru nxt_job_t *job;
1860Sigor@sysoev.ru nxt_work_handler_t handler;
1870Sigor@sysoev.ru
1880Sigor@sysoev.ru job = obj;
1890Sigor@sysoev.ru handler = (nxt_work_handler_t) data;
1900Sigor@sysoev.ru
1914Sigor@sysoev.ru job->task->thread = task->thread;
1921Sigor@sysoev.ru
1930Sigor@sysoev.ru if (nxt_slow_path(job->cancel)) {
1941Sigor@sysoev.ru nxt_debug(task, "%s cancellation", job->name);
1950Sigor@sysoev.ru handler = job->abort_handler;
1960Sigor@sysoev.ru }
1970Sigor@sysoev.ru
1984Sigor@sysoev.ru handler(job->task, job, job->data);
1990Sigor@sysoev.ru }
200