- if (valid_workq(workq) == 0) {
- return(EINVAL);
- }
-
- workqueue_list_lock();
- if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) {
- workqueue_list_unlock();
- return(ESRCH);
- }
-
- TAILQ_FOREACH(item, &workq->item_listhead, item_entry) {
- if (item == (pthread_workitem_t)itemhandle) {
- TAILQ_REMOVE(&workq->item_listhead, item, item_entry);
- if ((item->flags & (PTH_WQITEM_BARRIER | PTH_WQITEM_APPLIED)) == (PTH_WQITEM_BARRIER | PTH_WQITEM_APPLIED)) {
- workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON;
- workq->barrier_count = 0;
- if ((workq->queueprio < wqreadyprio) && (!(TAILQ_EMPTY(&workq->item_listhead)))) {
- wqreadyprio = workq->queueprio;
- }
- } else if ((item->flags & PTH_WQITEM_KERN_COUNT) == PTH_WQITEM_KERN_COUNT) {
- workq->kq_count--;
- item->flags |= PTH_WQITEM_REMOVED;
- if (handle_removeitem(workq, item) == 0)
- return(0);
- }
- item->flags |= PTH_WQITEM_NOTINLIST;
- free_workitem(item);
- workqueue_list_unlock();
- return(0);
- }
- }
-
- TAILQ_FOREACH(item, &workq->item_kernhead, item_entry) {
- if (item == (pthread_workitem_t)itemhandle) {
- workqueue_list_unlock();
- if ((error = __workq_ops(WQOPS_QUEUE_REMOVE, item, 0)) == 0) {
- workqueue_list_lock();
- TAILQ_REMOVE(&workq->item_kernhead, item, item_entry);
- OSAtomicDecrement32(&kernel_workq_count);
- workq->kq_count--;
- item->flags |= PTH_WQITEM_REMOVED;
- if (handle_removeitem(workq, item) != 0) {
- free_workitem(item);
- pick_nextworkqueue_droplock();
- }
- return(0);
- } else {
- workqueue_list_unlock();
- return(EBUSY);
- }
- }
- }
- workqueue_list_unlock();
- return(EINVAL);
-}
-
-
-int
-pthread_workqueue_addbarrier_np(pthread_workqueue_t workq, void (* callback_func)(pthread_workqueue_t, void *), void * callback_arg, __unused int waitforcallback, pthread_workitem_handle_t *itemhandlep)
-{
- pthread_workitem_t witem;
-
- if (valid_workq(workq) == 0) {
- return(EINVAL);
- }
-
- workqueue_list_lock();
-
- /*
- * Allocate the workitem here as it can drop the lock.
- * Also we can evaluate the workqueue state only once.
- */
- witem = alloc_workitem();
- witem->item_entry.tqe_next = 0;
- witem->item_entry.tqe_prev = 0;
- witem->func = callback_func;
- witem->func_arg = callback_arg;
- witem->flags = PTH_WQITEM_BARRIER;
-
- /* alloc workitem can drop the lock, check the state */
- if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) {
- free_workitem(witem);
- workqueue_list_unlock();
- return(ESRCH);
- }
-
- if (itemhandlep != NULL)
- *itemhandlep = (pthread_workitem_handle_t *)witem;
-
- TAILQ_INSERT_TAIL(&workq->item_listhead, witem, item_entry);