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)16*65Sigor@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) {
22*65Sigor@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
27*65Sigor@sysoev.ru job = nxt_mp_zget(mp, size);
280Sigor@sysoev.ru cache_size = 0;
290Sigor@sysoev.ru
300Sigor@sysoev.ru } else {
31*65Sigor@sysoev.ru job = nxt_mp_zalloc(mp, size);
320Sigor@sysoev.ru cache_size = size;
330Sigor@sysoev.ru }
340Sigor@sysoev.ru
350Sigor@sysoev.ru if (nxt_fast_path(job != NULL)) {
360Sigor@sysoev.ru job->cache_size = (uint16_t) cache_size;
370Sigor@sysoev.ru job->mem_pool = mp;
380Sigor@sysoev.ru nxt_job_set_name(job, "job");
390Sigor@sysoev.ru }
400Sigor@sysoev.ru
410Sigor@sysoev.ru /* Allow safe nxt_queue_remove() in nxt_job_destroy(). */
420Sigor@sysoev.ru nxt_queue_self(&job->link);
430Sigor@sysoev.ru
440Sigor@sysoev.ru return job;
450Sigor@sysoev.ru }
460Sigor@sysoev.ru
470Sigor@sysoev.ru
480Sigor@sysoev.ru void
nxt_job_init(nxt_job_t * job,size_t size)490Sigor@sysoev.ru nxt_job_init(nxt_job_t *job, size_t size)
500Sigor@sysoev.ru {
510Sigor@sysoev.ru nxt_memzero(job, size);
520Sigor@sysoev.ru
530Sigor@sysoev.ru nxt_job_set_name(job, "job");
540Sigor@sysoev.ru
550Sigor@sysoev.ru nxt_queue_self(&job->link);
560Sigor@sysoev.ru }
570Sigor@sysoev.ru
580Sigor@sysoev.ru
590Sigor@sysoev.ru void
nxt_job_destroy(nxt_task_t * task,void * data)6020Sigor@sysoev.ru nxt_job_destroy(nxt_task_t *task, void *data)
610Sigor@sysoev.ru {
620Sigor@sysoev.ru nxt_job_t *job;
630Sigor@sysoev.ru
640Sigor@sysoev.ru job = data;
650Sigor@sysoev.ru
660Sigor@sysoev.ru nxt_queue_remove(&job->link);
670Sigor@sysoev.ru
680Sigor@sysoev.ru if (job->cache_size == 0) {
690Sigor@sysoev.ru
700Sigor@sysoev.ru if (job->mem_pool != NULL) {
71*65Sigor@sysoev.ru nxt_mp_destroy(job->mem_pool);
720Sigor@sysoev.ru }
730Sigor@sysoev.ru
740Sigor@sysoev.ru } else {
75*65Sigor@sysoev.ru nxt_mp_free(job->mem_pool, job);
760Sigor@sysoev.ru }
770Sigor@sysoev.ru }
780Sigor@sysoev.ru
790Sigor@sysoev.ru
80*65Sigor@sysoev.ru #if 0
81*65Sigor@sysoev.ru
820Sigor@sysoev.ru nxt_int_t
83*65Sigor@sysoev.ru nxt_job_cleanup_add(nxt_mp_t *mp, nxt_job_t *job)
840Sigor@sysoev.ru {
850Sigor@sysoev.ru nxt_mem_pool_cleanup_t *mpcl;
860Sigor@sysoev.ru
870Sigor@sysoev.ru mpcl = nxt_mem_pool_cleanup(mp, 0);
880Sigor@sysoev.ru
890Sigor@sysoev.ru if (nxt_fast_path(mpcl != NULL)) {
900Sigor@sysoev.ru mpcl->handler = nxt_job_destroy;
910Sigor@sysoev.ru mpcl->data = job;
920Sigor@sysoev.ru return NXT_OK;
930Sigor@sysoev.ru }
940Sigor@sysoev.ru
950Sigor@sysoev.ru return NXT_ERROR;
960Sigor@sysoev.ru }
970Sigor@sysoev.ru
98*65Sigor@sysoev.ru #endif
99*65Sigor@sysoev.ru
1000Sigor@sysoev.ru
1010Sigor@sysoev.ru /*
1020Sigor@sysoev.ru * The (void *) casts in nxt_thread_pool_post() and nxt_event_engine_post()
1030Sigor@sysoev.ru * calls and to the "nxt_work_handler_t" are required by Sun C.
1040Sigor@sysoev.ru */
1050Sigor@sysoev.ru
1060Sigor@sysoev.ru void
nxt_job_start(nxt_task_t * task,nxt_job_t * job,nxt_work_handler_t handler)1071Sigor@sysoev.ru nxt_job_start(nxt_task_t *task, nxt_job_t *job, nxt_work_handler_t handler)
1080Sigor@sysoev.ru {
1091Sigor@sysoev.ru nxt_debug(task, "%s start", job->name);
1100Sigor@sysoev.ru
1110Sigor@sysoev.ru if (job->thread_pool != NULL) {
1120Sigor@sysoev.ru nxt_int_t ret;
1130Sigor@sysoev.ru
1141Sigor@sysoev.ru job->engine = task->thread->engine;
1151Sigor@sysoev.ru
1164Sigor@sysoev.ru nxt_work_set(&job->work, nxt_job_thread_trampoline,
1174Sigor@sysoev.ru job->task, job, (void *) handler);
1184Sigor@sysoev.ru
1194Sigor@sysoev.ru ret = nxt_thread_pool_post(job->thread_pool, &job->work);
1204Sigor@sysoev.ru
1210Sigor@sysoev.ru if (ret == NXT_OK) {
1220Sigor@sysoev.ru return;
1230Sigor@sysoev.ru }
1240Sigor@sysoev.ru
1250Sigor@sysoev.ru handler = job->abort_handler;
1260Sigor@sysoev.ru }
1270Sigor@sysoev.ru
1284Sigor@sysoev.ru handler(job->task, job, job->data);
1290Sigor@sysoev.ru }
1300Sigor@sysoev.ru
1310Sigor@sysoev.ru
1320Sigor@sysoev.ru /* A trampoline function is called by a thread pool thread. */
1330Sigor@sysoev.ru
1340Sigor@sysoev.ru static void
nxt_job_thread_trampoline(nxt_task_t * task,void * obj,void * data)1351Sigor@sysoev.ru nxt_job_thread_trampoline(nxt_task_t *task, void *obj, void *data)
1360Sigor@sysoev.ru {
1370Sigor@sysoev.ru nxt_job_t *job;
1380Sigor@sysoev.ru nxt_work_handler_t handler;
1390Sigor@sysoev.ru
1400Sigor@sysoev.ru job = obj;
1410Sigor@sysoev.ru handler = (nxt_work_handler_t) data;
1420Sigor@sysoev.ru
1431Sigor@sysoev.ru nxt_debug(task, "%s thread", job->name);
1440Sigor@sysoev.ru
1450Sigor@sysoev.ru if (nxt_slow_path(job->cancel)) {
1461Sigor@sysoev.ru nxt_job_return(task, job, job->abort_handler);
1470Sigor@sysoev.ru
1480Sigor@sysoev.ru } else {
1494Sigor@sysoev.ru handler(job->task, job, job->data);
1500Sigor@sysoev.ru }
1510Sigor@sysoev.ru }
1520Sigor@sysoev.ru
1530Sigor@sysoev.ru
1540Sigor@sysoev.ru void
nxt_job_return(nxt_task_t * task,nxt_job_t * job,nxt_work_handler_t handler)1551Sigor@sysoev.ru nxt_job_return(nxt_task_t *task, nxt_job_t *job, nxt_work_handler_t handler)
1560Sigor@sysoev.ru {
1571Sigor@sysoev.ru nxt_debug(task, "%s return", job->name);
1580Sigor@sysoev.ru
1590Sigor@sysoev.ru if (job->engine != NULL) {
1600Sigor@sysoev.ru /* A return function is called in thread pool thread context. */
1614Sigor@sysoev.ru
1624Sigor@sysoev.ru nxt_work_set(&job->work, nxt_job_thread_return_handler,
1634Sigor@sysoev.ru job->task, job, (void *) handler);
1644Sigor@sysoev.ru
1654Sigor@sysoev.ru nxt_event_engine_post(job->engine, &job->work);
1664Sigor@sysoev.ru
1670Sigor@sysoev.ru return;
1680Sigor@sysoev.ru }
1690Sigor@sysoev.ru
1700Sigor@sysoev.ru if (nxt_slow_path(job->cancel)) {
1711Sigor@sysoev.ru nxt_debug(task, "%s cancellation", job->name);
1720Sigor@sysoev.ru handler = job->abort_handler;
1730Sigor@sysoev.ru }
1740Sigor@sysoev.ru
1754Sigor@sysoev.ru nxt_work_queue_add(&task->thread->engine->fast_work_queue,
1764Sigor@sysoev.ru handler, job->task, job, job->data);
1770Sigor@sysoev.ru }
1780Sigor@sysoev.ru
1790Sigor@sysoev.ru
1800Sigor@sysoev.ru static void
nxt_job_thread_return_handler(nxt_task_t * task,void * obj,void * data)1811Sigor@sysoev.ru nxt_job_thread_return_handler(nxt_task_t *task, void *obj, void *data)
1820Sigor@sysoev.ru {
1830Sigor@sysoev.ru nxt_job_t *job;
1840Sigor@sysoev.ru nxt_work_handler_t handler;
1850Sigor@sysoev.ru
1860Sigor@sysoev.ru job = obj;
1870Sigor@sysoev.ru handler = (nxt_work_handler_t) data;
1880Sigor@sysoev.ru
1894Sigor@sysoev.ru job->task->thread = task->thread;
1901Sigor@sysoev.ru
1910Sigor@sysoev.ru if (nxt_slow_path(job->cancel)) {
1921Sigor@sysoev.ru nxt_debug(task, "%s cancellation", job->name);
1930Sigor@sysoev.ru handler = job->abort_handler;
1940Sigor@sysoev.ru }
1950Sigor@sysoev.ru
1964Sigor@sysoev.ru handler(job->task, job, job->data);
1970Sigor@sysoev.ru }
198