forked from Mirror/frr
Merge pull request #14724 from donaldsharp/workqueue_cleanup
Workqueue cleanup
This commit is contained in:
commit
4bdba57861
26
lib/buffer.h
26
lib/buffer.h
|
@ -14,21 +14,21 @@ extern "C" {
|
||||||
/* Create a new buffer. Memory will be allocated in chunks of the given
|
/* Create a new buffer. Memory will be allocated in chunks of the given
|
||||||
size. If the argument is 0, the library will supply a reasonable
|
size. If the argument is 0, the library will supply a reasonable
|
||||||
default size suitable for buffering socket I/O. */
|
default size suitable for buffering socket I/O. */
|
||||||
extern struct buffer *buffer_new(size_t);
|
extern struct buffer *buffer_new(size_t size);
|
||||||
|
|
||||||
/* Free all data in the buffer. */
|
/* Free all data in the buffer. */
|
||||||
extern void buffer_reset(struct buffer *);
|
extern void buffer_reset(struct buffer *b);
|
||||||
|
|
||||||
/* This function first calls buffer_reset to release all buffered data.
|
/* This function first calls buffer_reset to release all buffered data.
|
||||||
Then it frees the struct buffer itself. */
|
Then it frees the struct buffer itself. */
|
||||||
extern void buffer_free(struct buffer *);
|
extern void buffer_free(struct buffer *b);
|
||||||
|
|
||||||
/* Add the given data to the end of the buffer. */
|
/* Add the given data to the end of the buffer. */
|
||||||
extern void buffer_put(struct buffer *, const void *, size_t);
|
extern void buffer_put(struct buffer *b, const void *p, size_t size);
|
||||||
/* Add a single character to the end of the buffer. */
|
/* Add a single character to the end of the buffer. */
|
||||||
extern void buffer_putc(struct buffer *, uint8_t);
|
extern void buffer_putc(struct buffer *b, uint8_t c);
|
||||||
/* Add a NUL-terminated string to the end of the buffer. */
|
/* Add a NUL-terminated string to the end of the buffer. */
|
||||||
extern void buffer_putstr(struct buffer *, const char *);
|
extern void buffer_putstr(struct buffer *b, const char *str);
|
||||||
/* Add given data, inline-expanding \n to \r\n */
|
/* Add given data, inline-expanding \n to \r\n */
|
||||||
extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size);
|
extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size);
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size);
|
||||||
single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note
|
single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note
|
||||||
that this function does not alter the state of the buffer, so the data
|
that this function does not alter the state of the buffer, so the data
|
||||||
is still inside waiting to be flushed. */
|
is still inside waiting to be flushed. */
|
||||||
char *buffer_getstr(struct buffer *);
|
char *buffer_getstr(struct buffer *b);
|
||||||
|
|
||||||
/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */
|
/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */
|
||||||
int buffer_empty(struct buffer *);
|
int buffer_empty(struct buffer *b);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* An I/O error occurred. The buffer should be destroyed and the
|
/* An I/O error occurred. The buffer should be destroyed and the
|
||||||
|
@ -59,12 +59,12 @@ typedef enum {
|
||||||
|
|
||||||
/* Try to write this data to the file descriptor. Any data that cannot
|
/* Try to write this data to the file descriptor. Any data that cannot
|
||||||
be written immediately is added to the buffer queue. */
|
be written immediately is added to the buffer queue. */
|
||||||
extern buffer_status_t buffer_write(struct buffer *, int fd, const void *,
|
extern buffer_status_t buffer_write(struct buffer *b, int fd, const void *p,
|
||||||
size_t);
|
size_t size);
|
||||||
|
|
||||||
/* This function attempts to flush some (but perhaps not all) of
|
/* This function attempts to flush some (but perhaps not all) of
|
||||||
the queued data to the given file descriptor. */
|
the queued data to the given file descriptor. */
|
||||||
extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
|
extern buffer_status_t buffer_flush_available(struct buffer *b, int fd);
|
||||||
|
|
||||||
/* The following 2 functions (buffer_flush_all and buffer_flush_window)
|
/* The following 2 functions (buffer_flush_all and buffer_flush_window)
|
||||||
are for use in lib/vty.c only. They should not be used elsewhere. */
|
are for use in lib/vty.c only. They should not be used elsewhere. */
|
||||||
|
@ -72,7 +72,7 @@ extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
|
||||||
/* Call buffer_flush_available repeatedly until either all data has been
|
/* Call buffer_flush_available repeatedly until either all data has been
|
||||||
flushed, or an I/O error has been encountered, or the operation would
|
flushed, or an I/O error has been encountered, or the operation would
|
||||||
block. */
|
block. */
|
||||||
extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
|
extern buffer_status_t buffer_flush_all(struct buffer *b, int fd);
|
||||||
|
|
||||||
/* Attempt to write enough data to the given fd to fill a window of the
|
/* Attempt to write enough data to the given fd to fill a window of the
|
||||||
given width and height (and remove the data written from the buffer).
|
given width and height (and remove the data written from the buffer).
|
||||||
|
@ -85,7 +85,7 @@ extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
|
||||||
to return -1 (because the logic for handling the erase and more features
|
to return -1 (because the logic for handling the erase and more features
|
||||||
is too complicated to retry the write later).
|
is too complicated to retry the write later).
|
||||||
*/
|
*/
|
||||||
extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
|
extern buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
|
||||||
int height, int erase, int no_more);
|
int height, int erase, int no_more);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
40
lib/if.h
40
lib/if.h
|
@ -531,9 +531,9 @@ extern int if_cmp_name_func(const char *p1, const char *p2);
|
||||||
* This is useful for vrf route-leaking. So more than anything
|
* This is useful for vrf route-leaking. So more than anything
|
||||||
* else think before you use VRF_UNKNOWN
|
* else think before you use VRF_UNKNOWN
|
||||||
*/
|
*/
|
||||||
extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
|
extern void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
|
extern struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id);
|
||||||
extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex,
|
extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex,
|
||||||
vrf_id_t vrf_id);
|
vrf_id_t vrf_id);
|
||||||
extern struct interface *if_lookup_address_local(const void *matchaddr,
|
extern struct interface *if_lookup_address_local(const void *matchaddr,
|
||||||
|
@ -564,7 +564,7 @@ extern int if_set_index(struct interface *ifp, ifindex_t ifindex);
|
||||||
/* Delete the interface, but do not free the structure, and leave it in the
|
/* Delete the interface, but do not free the structure, and leave it in the
|
||||||
interface list. It is often advisable to leave the pseudo interface
|
interface list. It is often advisable to leave the pseudo interface
|
||||||
structure because there may be configuration information attached. */
|
structure because there may be configuration information attached. */
|
||||||
extern void if_delete_retain(struct interface *);
|
extern void if_delete_retain(struct interface *ifp);
|
||||||
|
|
||||||
/* Delete and free the interface structure: calls if_delete_retain and then
|
/* Delete and free the interface structure: calls if_delete_retain and then
|
||||||
deletes it from the interface list and frees the structure. */
|
deletes it from the interface list and frees the structure. */
|
||||||
|
@ -582,13 +582,13 @@ extern int if_is_pointopoint(const struct interface *ifp);
|
||||||
extern int if_is_multicast(const struct interface *ifp);
|
extern int if_is_multicast(const struct interface *ifp);
|
||||||
extern void if_terminate(struct vrf *vrf);
|
extern void if_terminate(struct vrf *vrf);
|
||||||
extern void if_dump_all(void);
|
extern void if_dump_all(void);
|
||||||
extern const char *if_flag_dump(unsigned long);
|
extern const char *if_flag_dump(unsigned long flags);
|
||||||
extern const char *if_link_type_str(enum zebra_link_type);
|
extern const char *if_link_type_str(enum zebra_link_type zlt);
|
||||||
|
|
||||||
/* Please use ifindex2ifname instead of if_indextoname where possible;
|
/* Please use ifindex2ifname instead of if_indextoname where possible;
|
||||||
ifindex2ifname uses internal interface info, whereas if_indextoname must
|
ifindex2ifname uses internal interface info, whereas if_indextoname must
|
||||||
make a system call. */
|
make a system call. */
|
||||||
extern const char *ifindex2ifname(ifindex_t, vrf_id_t vrf_id);
|
extern const char *ifindex2ifname(ifindex_t ifindex, vrf_id_t vrf_id);
|
||||||
|
|
||||||
/* Please use ifname2ifindex instead of if_nametoindex where possible;
|
/* Please use ifname2ifindex instead of if_nametoindex where possible;
|
||||||
ifname2ifindex uses internal interface info, whereas if_nametoindex must
|
ifname2ifindex uses internal interface info, whereas if_nametoindex must
|
||||||
|
@ -598,18 +598,20 @@ extern ifindex_t ifname2ifindex(const char *ifname, vrf_id_t vrf_id);
|
||||||
/* Connected address functions. */
|
/* Connected address functions. */
|
||||||
extern struct connected *connected_new(void);
|
extern struct connected *connected_new(void);
|
||||||
extern void connected_free(struct connected **connected);
|
extern void connected_free(struct connected **connected);
|
||||||
extern struct connected *
|
extern struct connected *connected_add_by_prefix(struct interface *ifp,
|
||||||
connected_add_by_prefix(struct interface *, struct prefix *, struct prefix *);
|
struct prefix *p,
|
||||||
extern struct connected *connected_delete_by_prefix(struct interface *,
|
struct prefix *dest);
|
||||||
struct prefix *);
|
extern struct connected *connected_delete_by_prefix(struct interface *ifp,
|
||||||
extern struct connected *connected_lookup_prefix(struct interface *,
|
struct prefix *p);
|
||||||
const struct prefix *);
|
extern struct connected *connected_lookup_prefix(struct interface *ifp,
|
||||||
extern struct connected *connected_lookup_prefix_exact(struct interface *,
|
const struct prefix *p);
|
||||||
const struct prefix *);
|
extern struct connected *connected_lookup_prefix_exact(struct interface *ifp,
|
||||||
extern unsigned int connected_count_by_family(struct interface *, int family);
|
const struct prefix *p);
|
||||||
|
extern unsigned int connected_count_by_family(struct interface *ifp, int family);
|
||||||
extern struct nbr_connected *nbr_connected_new(void);
|
extern struct nbr_connected *nbr_connected_new(void);
|
||||||
extern void nbr_connected_free(struct nbr_connected *);
|
extern void nbr_connected_free(struct nbr_connected *connected);
|
||||||
struct nbr_connected *nbr_connected_check(struct interface *, struct prefix *);
|
struct nbr_connected *nbr_connected_check(struct interface *ifp,
|
||||||
|
struct prefix *p);
|
||||||
struct connected *connected_get_linklocal(struct interface *ifp);
|
struct connected *connected_get_linklocal(struct interface *ifp);
|
||||||
|
|
||||||
/* link parameters */
|
/* link parameters */
|
||||||
|
@ -617,10 +619,10 @@ bool if_link_params_cmp(struct if_link_params *iflp1,
|
||||||
struct if_link_params *iflp2);
|
struct if_link_params *iflp2);
|
||||||
void if_link_params_copy(struct if_link_params *dst,
|
void if_link_params_copy(struct if_link_params *dst,
|
||||||
struct if_link_params *src);
|
struct if_link_params *src);
|
||||||
struct if_link_params *if_link_params_get(struct interface *);
|
struct if_link_params *if_link_params_get(struct interface *ifp);
|
||||||
struct if_link_params *if_link_params_enable(struct interface *ifp);
|
struct if_link_params *if_link_params_enable(struct interface *ifp);
|
||||||
struct if_link_params *if_link_params_init(struct interface *ifp);
|
struct if_link_params *if_link_params_init(struct interface *ifp);
|
||||||
void if_link_params_free(struct interface *);
|
void if_link_params_free(struct interface *ifp);
|
||||||
|
|
||||||
/* Northbound. */
|
/* Northbound. */
|
||||||
struct vty;
|
struct vty;
|
||||||
|
|
|
@ -42,6 +42,15 @@ static void work_queue_item_free(struct work_queue_item *item)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void work_queue_item_dequeue(struct work_queue *wq,
|
||||||
|
struct work_queue_item *item)
|
||||||
|
{
|
||||||
|
assert(wq->item_count > 0);
|
||||||
|
|
||||||
|
wq->item_count--;
|
||||||
|
STAILQ_REMOVE(&wq->items, item, work_queue_item, wq);
|
||||||
|
}
|
||||||
|
|
||||||
static void work_queue_item_remove(struct work_queue *wq,
|
static void work_queue_item_remove(struct work_queue *wq,
|
||||||
struct work_queue_item *item)
|
struct work_queue_item *item)
|
||||||
{
|
{
|
||||||
|
@ -133,6 +142,13 @@ static int work_queue_schedule(struct work_queue *wq, unsigned int delay)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void work_queue_item_enqueue(struct work_queue *wq,
|
||||||
|
struct work_queue_item *item)
|
||||||
|
{
|
||||||
|
STAILQ_INSERT_TAIL(&wq->items, item, wq);
|
||||||
|
wq->item_count++;
|
||||||
|
}
|
||||||
|
|
||||||
void work_queue_add(struct work_queue *wq, void *data)
|
void work_queue_add(struct work_queue *wq, void *data)
|
||||||
{
|
{
|
||||||
struct work_queue_item *item;
|
struct work_queue_item *item;
|
||||||
|
@ -265,8 +281,7 @@ void work_queue_run(struct event *thread)
|
||||||
do {
|
do {
|
||||||
ret = wq->spec.workfunc(wq, item->data);
|
ret = wq->spec.workfunc(wq, item->data);
|
||||||
item->ran++;
|
item->ran++;
|
||||||
} while ((ret == WQ_RETRY_NOW)
|
} while (item->ran < wq->spec.max_retries);
|
||||||
&& (item->ran < wq->spec.max_retries));
|
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case WQ_QUEUE_BLOCKED: {
|
case WQ_QUEUE_BLOCKED: {
|
||||||
|
@ -276,9 +291,6 @@ void work_queue_run(struct event *thread)
|
||||||
item->ran--;
|
item->ran--;
|
||||||
goto stats;
|
goto stats;
|
||||||
}
|
}
|
||||||
case WQ_RETRY_LATER: {
|
|
||||||
goto stats;
|
|
||||||
}
|
|
||||||
case WQ_REQUEUE: {
|
case WQ_REQUEUE: {
|
||||||
item->ran--;
|
item->ran--;
|
||||||
work_queue_item_requeue(wq, item);
|
work_queue_item_requeue(wq, item);
|
||||||
|
@ -296,11 +308,6 @@ void work_queue_run(struct event *thread)
|
||||||
titem = item;
|
titem = item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WQ_RETRY_NOW:
|
|
||||||
/* a RETRY_NOW that gets here has exceeded max_tries, same
|
|
||||||
* as ERROR
|
|
||||||
*/
|
|
||||||
fallthrough;
|
|
||||||
case WQ_SUCCESS:
|
case WQ_SUCCESS:
|
||||||
default: {
|
default: {
|
||||||
work_queue_item_remove(wq, item);
|
work_queue_item_remove(wq, item);
|
||||||
|
@ -352,8 +359,7 @@ stats:
|
||||||
|
|
||||||
/* Is the queue done yet? If it is, call the completion callback. */
|
/* Is the queue done yet? If it is, call the completion callback. */
|
||||||
if (!work_queue_empty(wq)) {
|
if (!work_queue_empty(wq)) {
|
||||||
if (ret == WQ_RETRY_LATER ||
|
if (ret == WQ_QUEUE_BLOCKED)
|
||||||
ret == WQ_QUEUE_BLOCKED)
|
|
||||||
work_queue_schedule(wq, wq->spec.retry);
|
work_queue_schedule(wq, wq->spec.retry);
|
||||||
else
|
else
|
||||||
work_queue_schedule(wq, 0);
|
work_queue_schedule(wq, 0);
|
||||||
|
|
|
@ -26,9 +26,7 @@ DECLARE_MTYPE(WORK_QUEUE);
|
||||||
/* action value, for use by item processor and item error handlers */
|
/* action value, for use by item processor and item error handlers */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WQ_SUCCESS = 0,
|
WQ_SUCCESS = 0,
|
||||||
WQ_RETRY_NOW, /* retry immediately */
|
WQ_REQUEUE, /* requeue item, continue processing work queue */
|
||||||
WQ_RETRY_LATER, /* retry later, cease processing work queue */
|
|
||||||
WQ_REQUEUE, /* requeue item, continue processing work queue */
|
|
||||||
WQ_QUEUE_BLOCKED, /* Queue cant be processed at this time.
|
WQ_QUEUE_BLOCKED, /* Queue cant be processed at this time.
|
||||||
* Similar to WQ_RETRY_LATER, but doesn't penalise
|
* Similar to WQ_RETRY_LATER, but doesn't penalise
|
||||||
* the particular item.. */
|
* the particular item.. */
|
||||||
|
@ -117,22 +115,6 @@ work_queue_last_item(struct work_queue *wq)
|
||||||
return STAILQ_LAST(&wq->items, work_queue_item, wq);
|
return STAILQ_LAST(&wq->items, work_queue_item, wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void work_queue_item_enqueue(struct work_queue *wq,
|
|
||||||
struct work_queue_item *item)
|
|
||||||
{
|
|
||||||
STAILQ_INSERT_TAIL(&wq->items, item, wq);
|
|
||||||
wq->item_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void work_queue_item_dequeue(struct work_queue *wq,
|
|
||||||
struct work_queue_item *item)
|
|
||||||
{
|
|
||||||
assert(wq->item_count > 0);
|
|
||||||
|
|
||||||
wq->item_count--;
|
|
||||||
STAILQ_REMOVE(&wq->items, item, work_queue_item, wq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a new work queue, of given name.
|
/* create a new work queue, of given name.
|
||||||
* user must fill in the spec of the returned work queue before adding
|
* user must fill in the spec of the returned work queue before adding
|
||||||
* anything to it
|
* anything to it
|
||||||
|
@ -160,6 +142,7 @@ bool work_queue_is_scheduled(struct work_queue *wq);
|
||||||
/* Helpers, exported for thread.c and command.c */
|
/* Helpers, exported for thread.c and command.c */
|
||||||
extern void work_queue_run(struct event *thread);
|
extern void work_queue_run(struct event *thread);
|
||||||
|
|
||||||
|
/* Function to initialize the workqueue cli */
|
||||||
extern void workqueue_cmd_init(void);
|
extern void workqueue_cmd_init(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -76,12 +76,6 @@ static wq_item_status slow_func(struct work_queue *wq, void *data)
|
||||||
for (j = 0; j < 300; j++)
|
for (j = 0; j < 300; j++)
|
||||||
x += sin(x) * j;
|
x += sin(x) * j;
|
||||||
|
|
||||||
if ((hn->i % ITERS_LATER) == 0)
|
|
||||||
return WQ_RETRY_LATER;
|
|
||||||
|
|
||||||
if ((hn->i % ITERS_ERR) == 0)
|
|
||||||
return WQ_RETRY_NOW;
|
|
||||||
|
|
||||||
if ((hn->i % ITERS_PRINT) == 0)
|
if ((hn->i % ITERS_PRINT) == 0)
|
||||||
printf("%s did %d, x = %g\n", hn->str, hn->i, x);
|
printf("%s did %d, x = %g\n", hn->str, hn->i, x);
|
||||||
|
|
||||||
|
|
|
@ -396,6 +396,7 @@ void lua_pushzebra_dplane_ctx(lua_State *L, const struct zebra_dplane_ctx *ctx)
|
||||||
lua_setfield(L, -2, "mtu");
|
lua_setfield(L, -2, "mtu");
|
||||||
}
|
}
|
||||||
lua_setfield(L, -2, "gre");
|
lua_setfield(L, -2, "gre");
|
||||||
|
break;
|
||||||
|
|
||||||
case DPLANE_OP_ADDR_INSTALL:
|
case DPLANE_OP_ADDR_INSTALL:
|
||||||
case DPLANE_OP_ADDR_UNINSTALL:
|
case DPLANE_OP_ADDR_UNINSTALL:
|
||||||
|
|
Loading…
Reference in a new issue