backport to buster
[hcoop/debian/openafs.git] / src / util / work_queue_impl_types.h
1 /*
2 * Copyright 2008-2010, Sine Nomine Associates and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #ifndef AFS_UTIL_WORK_QUEUE_IMPL_TYPES_H
11 #define AFS_UTIL_WORK_QUEUE_IMPL_TYPES_H 1
12
13 #ifndef __AFS_WORK_QUEUE_IMPL
14 #error "do not include this file outside of the work queue implementation"
15 #endif
16
17 #include "work_queue_types.h"
18 #include <rx/rx_queue.h>
19
20 /**
21 * implementation-private type definitions for work_queue.
22 */
23
24 /**
25 * work_queue node state.
26 */
27 typedef enum {
28 AFS_WQ_NODE_STATE_INIT, /**< initial state */
29 AFS_WQ_NODE_STATE_SCHEDULED, /**< scheduled for execution */
30 AFS_WQ_NODE_STATE_RUNNING, /**< running callback function */
31 AFS_WQ_NODE_STATE_DONE, /**< callback function finished */
32 AFS_WQ_NODE_STATE_ERROR, /**< node callback failed, or some dep failed */
33 AFS_WQ_NODE_STATE_BLOCKED, /**< pending some dependency */
34 AFS_WQ_NODE_STATE_BUSY, /**< exclusively owned by a thread */
35 /* add new states above this line */
36 AFS_WQ_NODE_STATE_TERMINAL
37 } afs_wq_work_state_t;
38
39 /**
40 * work_queue dependency node.
41 */
42 struct afs_work_queue_dep_node {
43 struct rx_queue parent_list; /**< parent node's list of children */
44 struct afs_work_queue_node * parent; /**< parent work node */
45 struct afs_work_queue_node * child; /**< child work node */
46 /* coming soon: dep options */
47 };
48
49 /**
50 * work_queue enumeration.
51 *
52 * tells which linked list a given node is attached to.
53 */
54 typedef enum {
55 AFS_WQ_NODE_LIST_NONE, /**< node is not on a linked list. */
56 AFS_WQ_NODE_LIST_READY, /**< node is on ready_list */
57 AFS_WQ_NODE_LIST_BLOCKED, /**< node is on blocked_list */
58 AFS_WQ_NODE_LIST_DONE, /**< node is on done_list */
59 /* add new queues above this line */
60 AFS_WQ_NODE_LIST_TERMINAL
61 } afs_wq_node_list_id_t;
62
63 /**
64 * work_queue node.
65 */
66 struct afs_work_queue_node {
67 struct rx_queue node_list; /**< linked list of work queue nodes. */
68 afs_wq_node_list_id_t qidx; /**< id of linked list */
69 struct rx_queue dep_children; /**< nodes whose execution depends upon
70 * our completion. */
71 afs_wq_callback_func_t * cbf;
72 /**< callback function which will be called by scheduler */
73 afs_wq_callback_dtor_t *rock_dtor; /**< destructor function for 'rock' */
74 void * rock; /**< opaque pointer passed into cbf */
75 struct afs_work_queue * queue; /**< our queue */
76 afs_wq_work_state_t state; /**< state of this queue node */
77 afs_uint32 refcount; /**< object reference count */
78 afs_uint32 block_count; /**< dependency blocking count; node is
79 * only a candidate for execution when
80 * this counter reaches zero. */
81 afs_uint32 error_count; /**< dependency error count; node is only
82 * a candidate for execution when this
83 * counter reaches zero. */
84 int detached; /**< object is put instead of being placed onto done queue */
85 int retcode; /**< return code from worker function */
86 pthread_mutex_t lock; /**< object lock */
87 pthread_cond_t state_cv; /**< state change cv */
88 };
89
90 /**
91 * linked list
92 */
93 struct afs_work_queue_node_list {
94 struct rx_queue list; /**< linked list of nodes */
95 afs_wq_node_list_id_t qidx; /**< id of linked list */
96 int shutdown; /**< don't allow blocking on dequeue if asserted */
97 pthread_mutex_t lock; /**< synchronize list access */
98 pthread_cond_t cv; /**< signal empty->non-empty transition */
99 };
100
101 /**
102 * multilock control structure.
103 */
104 struct afs_work_queue_node_multilock {
105 struct {
106 struct afs_work_queue_node * node;
107 int lock_held;
108 int busy_held;
109 } nodes[2];
110 };
111
112 /**
113 * work queue.
114 */
115 struct afs_work_queue {
116 struct afs_work_queue_node_list ready_list; /**< ready work queue nodes. */
117 struct afs_work_queue_node_list blocked_list; /**< nodes scheduled, but blocked */
118 struct afs_work_queue_node_list done_list; /**< nodes done/errored */
119 void * rock; /**< opaque pointer passed to all callbacks */
120
121 struct afs_work_queue_opts opts;
122
123 int drain; /**< 1 if we are waiting for the queue to drain
124 * until the number of pending tasks has
125 * dropped below the low threshold */
126 int shutdown; /**< 1 if the queue has been shutdown */
127 int pend_count; /**< number of pending tasks */
128 int running_count; /**< number of tasks busy running */
129 pthread_mutex_t lock; /**< lock for the queue */
130 pthread_cond_t pend_cv; /**< signalled when th queue is draining and
131 * the number of pending tasks dropped below
132 * the low threshold */
133 pthread_cond_t empty_cv; /**< signalled when the number of pending tasks
134 * reaches 0 */
135 pthread_cond_t running_cv; /**< signalled once running_count reaches 0 and
136 * the queue is shutting down */
137 };
138
139 #endif /* AFS_UTIL_WORK_QUEUE_IMPL_TYPES_H */