12 struct list_head node
;
15 void (*job_cb
)(void *data
);
16 void (*free_cb
)(void *data
);
20 static LIST_HEAD(worker_job_head
);
21 static pthread_mutex_t worker_mutex
= CMUS_MUTEX_INITIALIZER
;
22 static pthread_t worker_thread
;
23 static int running
= 1;
24 static int cancel_type
= JOB_TYPE_NONE
;
27 * - only worker thread modifies this
28 * - cur_job->job_cb can read this without locking
29 * - anyone else must lock worker before reading this
31 static struct worker_job
*cur_job
= NULL
;
33 #define worker_lock() cmus_mutex_lock(&worker_mutex)
34 #define worker_unlock() cmus_mutex_unlock(&worker_mutex)
36 static void *worker_loop(void *arg
)
40 if (list_empty(&worker_job_head
)) {
48 struct list_head
*item
= worker_job_head
.next
;
52 cur_job
= container_of(item
, struct worker_job
, node
);
56 cur_job
->job_cb(cur_job
->data
);
58 timer_print("worker job", et
- st
);
61 cur_job
->free_cb(cur_job
->data
);
69 void worker_init(void)
71 int rc
= pthread_create(&worker_thread
, NULL
, worker_loop
, NULL
);
76 void worker_exit(void)
82 pthread_join(worker_thread
, NULL
);
85 void worker_add_job(int type
, void (*job_cb
)(void *data
),
86 void (*free_cb
)(void *data
), void *data
)
88 struct worker_job
*job
;
90 job
= xnew(struct worker_job
, 1);
93 job
->free_cb
= free_cb
;
97 list_add_tail(&job
->node
, &worker_job_head
);
101 void worker_remove_jobs(int type
)
103 struct list_head
*item
;
108 /* remove jobs of the specified type from the queue */
109 item
= worker_job_head
.next
;
110 while (item
!= &worker_job_head
) {
111 struct worker_job
*job
= container_of(item
, struct worker_job
, node
);
112 struct list_head
*next
= item
->next
;
114 if (type
== JOB_TYPE_ANY
|| type
== job
->type
) {
115 list_del(&job
->node
);
116 job
->free_cb(job
->data
);
122 /* wait current job to finish or cancel if it's of the specified type */
123 while (cur_job
&& (type
== JOB_TYPE_ANY
|| type
== cur_job
->type
)) {
129 cancel_type
= JOB_TYPE_NONE
;
134 * this is only called from the worker thread
135 * cur_job is guaranteed to be non-NULL
137 int worker_cancelling(void)
139 return cur_job
->type
== cancel_type
|| cancel_type
== JOB_TYPE_ANY
;