| /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de) |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef __mod_h2__h2_worker__ |
| #define __mod_h2__h2_worker__ |
| |
| struct h2_mplx; |
| struct h2_request; |
| struct h2_task; |
| |
| /* h2_worker is a basically a apr_thread_t that reads fromt he h2_workers |
| * task queue and runs h2_tasks it is given. |
| */ |
| typedef struct h2_worker h2_worker; |
| |
| /* Invoked when the worker wants a new task to process. Will block |
| * until a h2_mplx becomes available or the worker itself |
| * gets aborted (idle timeout, for example). */ |
| typedef apr_status_t h2_worker_mplx_next_fn(h2_worker *worker, |
| void *ctx, |
| struct h2_task **ptask, |
| int *psticky); |
| |
| /* Invoked just before the worker thread exits. */ |
| typedef void h2_worker_done_fn(h2_worker *worker, void *ctx); |
| |
| |
| struct h2_worker { |
| int id; |
| /** Links to the rest of the workers */ |
| APR_RING_ENTRY(h2_worker) link; |
| apr_thread_t *thread; |
| h2_worker_mplx_next_fn *get_next; |
| h2_worker_done_fn *worker_done; |
| void *ctx; |
| int aborted; |
| }; |
| |
| /** |
| * The magic pointer value that indicates the head of a h2_worker list |
| * @param b The worker list |
| * @return The magic pointer value |
| */ |
| #define H2_WORKER_LIST_SENTINEL(b) APR_RING_SENTINEL((b), h2_worker, link) |
| |
| /** |
| * Determine if the worker list is empty |
| * @param b The list to check |
| * @return true or false |
| */ |
| #define H2_WORKER_LIST_EMPTY(b) APR_RING_EMPTY((b), h2_worker, link) |
| |
| /** |
| * Return the first worker in a list |
| * @param b The list to query |
| * @return The first worker in the list |
| */ |
| #define H2_WORKER_LIST_FIRST(b) APR_RING_FIRST(b) |
| |
| /** |
| * Return the last worker in a list |
| * @param b The list to query |
| * @return The last worker int he list |
| */ |
| #define H2_WORKER_LIST_LAST(b) APR_RING_LAST(b) |
| |
| /** |
| * Insert a single worker at the front of a list |
| * @param b The list to add to |
| * @param e The worker to insert |
| */ |
| #define H2_WORKER_LIST_INSERT_HEAD(b, e) do { \ |
| h2_worker *ap__b = (e); \ |
| APR_RING_INSERT_HEAD((b), ap__b, h2_worker, link); \ |
| } while (0) |
| |
| /** |
| * Insert a single worker at the end of a list |
| * @param b The list to add to |
| * @param e The worker to insert |
| */ |
| #define H2_WORKER_LIST_INSERT_TAIL(b, e) do { \ |
| h2_worker *ap__b = (e); \ |
| APR_RING_INSERT_TAIL((b), ap__b, h2_worker, link); \ |
| } while (0) |
| |
| /** |
| * Get the next worker in the list |
| * @param e The current worker |
| * @return The next worker |
| */ |
| #define H2_WORKER_NEXT(e) APR_RING_NEXT((e), link) |
| /** |
| * Get the previous worker in the list |
| * @param e The current worker |
| * @return The previous worker |
| */ |
| #define H2_WORKER_PREV(e) APR_RING_PREV((e), link) |
| |
| /** |
| * Remove a worker from its list |
| * @param e The worker to remove |
| */ |
| #define H2_WORKER_REMOVE(e) APR_RING_REMOVE((e), link) |
| |
| |
| /* Create a new worker with given id, pool and attributes, callbacks |
| * callback parameter. |
| */ |
| h2_worker *h2_worker_create(int id, |
| apr_pool_t *pool, |
| apr_threadattr_t *attr, |
| h2_worker_mplx_next_fn *get_next, |
| h2_worker_done_fn *worker_done, |
| void *ctx); |
| |
| apr_status_t h2_worker_destroy(h2_worker *worker); |
| |
| void h2_worker_abort(h2_worker *worker); |
| |
| int h2_worker_is_aborted(h2_worker *worker); |
| |
| #endif /* defined(__mod_h2__h2_worker__) */ |