]> granicus.if.org Git - apache/blob - modules/http2/h2_worker.c
CHANGES: backported features to 2.4.x
[apache] / modules / http2 / h2_worker.c
1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <assert.h>
17
18 #include <apr_thread_cond.h>
19
20 #include <mpm_common.h>
21 #include <httpd.h>
22 #include <http_core.h>
23 #include <http_log.h>
24
25 #include "h2.h"
26 #include "h2_private.h"
27 #include "h2_conn.h"
28 #include "h2_ctx.h"
29 #include "h2_h2.h"
30 #include "h2_mplx.h"
31 #include "h2_task.h"
32 #include "h2_worker.h"
33
34 static void* APR_THREAD_FUNC execute(apr_thread_t *thread, void *wctx)
35 {
36     h2_worker *worker = (h2_worker *)wctx;
37     int sticky;
38     
39     while (!worker->aborted) {
40         h2_task *task;
41         
42         /* Get a h2_task from the main workers queue. */
43         worker->get_next(worker, worker->ctx, &task, &sticky);
44         while (task) {
45         
46             h2_task_do(task, thread, worker->id);
47             /* report the task done and maybe get another one from the same
48              * mplx (= master connection), if we can be sticky. 
49              */
50             if (sticky && !worker->aborted) {
51                 h2_mplx_task_done(task->mplx, task, &task);
52             }
53             else {
54                 h2_mplx_task_done(task->mplx, task, NULL);
55                 task = NULL;
56             }
57         }
58     }
59
60     worker->worker_done(worker, worker->ctx);
61     return NULL;
62 }
63
64 h2_worker *h2_worker_create(int id,
65                             apr_pool_t *pool,
66                             apr_threadattr_t *attr,
67                             h2_worker_mplx_next_fn *get_next,
68                             h2_worker_done_fn *worker_done,
69                             void *ctx)
70 {
71     h2_worker *w = apr_pcalloc(pool, sizeof(h2_worker));
72     if (w) {
73         w->id = id;
74         APR_RING_ELEM_INIT(w, link);
75         w->get_next = get_next;
76         w->worker_done = worker_done;
77         w->ctx = ctx;
78         apr_thread_create(&w->thread, attr, execute, w, pool);
79     }
80     return w;
81 }
82
83 apr_status_t h2_worker_destroy(h2_worker *worker)
84 {
85     if (worker->thread) {
86         apr_status_t status;
87         apr_thread_join(&status, worker->thread);
88         worker->thread = NULL;
89     }
90     return APR_SUCCESS;
91 }
92
93 void h2_worker_abort(h2_worker *worker)
94 {
95     worker->aborted = 1;
96 }
97
98 int h2_worker_is_aborted(h2_worker *worker)
99 {
100     return worker->aborted;
101 }
102
103