xref: /unit/src/nxt_job.c (revision 2403:81b1e3a34636)
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