xref: /unit/src/nxt_job.c (revision 223:bf98efe2c55c)
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