+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Quagga Work Queue Support.
*
* Copyright (C) 2005 Sun Microsystems, Inc.
- *
- * This file is part of GNU Zebra.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
-#include "thread.h"
+#include "event.h"
#include "memory.h"
#include "workqueue.h"
#include "linklist.h"
}
/* create new work queue */
-struct work_queue *work_queue_new(struct thread_master *m,
+struct work_queue *work_queue_new(struct event_master *m,
const char *queue_name)
{
struct work_queue *new;
/* Default values, can be overridden by caller */
new->spec.hold = WORK_QUEUE_DEFAULT_HOLD;
- new->spec.yield = THREAD_YIELD_TIME_SLOT;
+ new->spec.yield = EVENT_YIELD_TIME_SLOT;
new->spec.retry = WORK_QUEUE_DEFAULT_RETRY;
return new;
{
struct work_queue *wq = *wqp;
- if (wq->thread != NULL)
- thread_cancel(&(wq->thread));
+ EVENT_OFF(wq->thread);
while (!work_queue_empty(wq)) {
struct work_queue_item *item = work_queue_last_item(wq);
bool work_queue_is_scheduled(struct work_queue *wq)
{
- return (wq->thread != NULL);
+ return event_is_scheduled(wq->thread);
}
static int work_queue_schedule(struct work_queue *wq, unsigned int delay)
{
/* if appropriate, schedule work queue thread */
- if (CHECK_FLAG(wq->flags, WQ_UNPLUGGED) && (wq->thread == NULL)
- && !work_queue_empty(wq)) {
- wq->thread = NULL;
-
+ if (CHECK_FLAG(wq->flags, WQ_UNPLUGGED) &&
+ !event_is_scheduled(wq->thread) && !work_queue_empty(wq)) {
/* Schedule timer if there's a delay, otherwise just schedule
* as an 'event'
*/
if (delay > 0) {
- thread_add_timer_msec(wq->master, work_queue_run, wq,
- delay, &wq->thread);
- thread_ignore_late_timer(wq->thread);
+ event_add_timer_msec(wq->master, work_queue_run, wq,
+ delay, &wq->thread);
+ event_ignore_late_timer(wq->thread);
} else
- thread_add_event(wq->master, work_queue_run, wq, 0,
- &wq->thread);
+ event_add_event(wq->master, work_queue_run, wq, 0,
+ &wq->thread);
/* set thread yield time, if needed */
- if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT)
- thread_set_yield_time(wq->thread, wq->spec.yield);
+ if (event_is_scheduled(wq->thread) &&
+ wq->spec.yield != EVENT_YIELD_TIME_SLOT)
+ event_set_yield_time(wq->thread, wq->spec.yield);
return 1;
} else
return 0;
*/
void work_queue_plug(struct work_queue *wq)
{
- if (wq->thread)
- thread_cancel(&(wq->thread));
-
- wq->thread = NULL;
+ EVENT_OFF(wq->thread);
UNSET_FLAG(wq->flags, WQ_UNPLUGGED);
}
* will reschedule itself if required,
* otherwise work_queue_item_add
*/
-int work_queue_run(struct thread *thread)
+void work_queue_run(struct event *thread)
{
struct work_queue *wq;
struct work_queue_item *item, *titem;
unsigned int cycles = 0;
char yielded = 0;
- wq = THREAD_ARG(thread);
+ wq = EVENT_ARG(thread);
assert(wq);
- wq->thread = NULL;
-
/* calculate cycle granularity:
* list iteration == 1 run
* listnode processing == 1 cycle
/* dont run items which are past their allowed retries */
if (item->ran > wq->spec.max_retries) {
- /* run error handler, if any */
- if (wq->spec.errorfunc)
- wq->spec.errorfunc(wq, item);
work_queue_item_remove(wq, item);
continue;
}
case WQ_RETRY_NOW:
/* a RETRY_NOW that gets here has exceeded max_tries, same as
* ERROR */
- case WQ_ERROR: {
- if (wq->spec.errorfunc)
- wq->spec.errorfunc(wq, item);
- }
/* fallthru */
case WQ_SUCCESS:
default: {
cycles++;
/* test if we should yield */
- if (!(cycles % wq->cycles.granularity)
- && thread_should_yield(thread)) {
+ if (!(cycles % wq->cycles.granularity) &&
+ event_should_yield(thread)) {
yielded = 1;
goto stats;
}
} else if (wq->spec.completion_func)
wq->spec.completion_func(wq);
-
- return 0;
}