lib: change thread_add_* API

Do not return pointer to the newly created thread from various thread_add
functions. This should prevent developers from storing a thread pointer
into some variable without letting the lib know that the pointer is
stored. When the lib doesn't know that the pointer is stored, it doesn't
prevent rescheduling and it can lead to hard to find bugs. If someone
wants to store the pointer, they should pass a double pointer as the last
argument.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
Igor Ryzhov 2021-10-06 22:06:23 +03:00
parent 5db95752c0
commit ee1455dd98
6 changed files with 59 additions and 72 deletions

View File

@ -922,10 +922,10 @@ done:
} }
/* Add new read thread. */ /* Add new read thread. */
struct thread *_thread_add_read_write(const struct xref_threadsched *xref, void _thread_add_read_write(const struct xref_threadsched *xref,
struct thread_master *m, struct thread_master *m,
int (*func)(struct thread *), int (*func)(struct thread *), void *arg, int fd,
void *arg, int fd, struct thread **t_ptr) struct thread **t_ptr)
{ {
int dir = xref->thread_type; int dir = xref->thread_type;
struct thread *thread = NULL; struct thread *thread = NULL;
@ -1000,15 +1000,13 @@ struct thread *_thread_add_read_write(const struct xref_threadsched *xref,
AWAKEN(m); AWAKEN(m);
} }
return thread;
} }
static struct thread * static void _thread_add_timer_timeval(const struct xref_threadsched *xref,
_thread_add_timer_timeval(const struct xref_threadsched *xref, struct thread_master *m,
struct thread_master *m, int (*func)(struct thread *), int (*func)(struct thread *), void *arg,
void *arg, struct timeval *time_relative, struct timeval *time_relative,
struct thread **t_ptr) struct thread **t_ptr)
{ {
struct thread *thread; struct thread *thread;
struct timeval t; struct timeval t;
@ -1028,7 +1026,7 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref,
frr_with_mutex(&m->mtx) { frr_with_mutex(&m->mtx) {
if (t_ptr && *t_ptr) if (t_ptr && *t_ptr)
/* thread is already scheduled; don't reschedule */ /* thread is already scheduled; don't reschedule */
return NULL; return;
thread = thread_get(m, THREAD_TIMER, func, arg, xref); thread = thread_get(m, THREAD_TIMER, func, arg, xref);
@ -1048,16 +1046,13 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref,
if (thread_timer_list_first(&m->timer) == thread) if (thread_timer_list_first(&m->timer) == thread)
AWAKEN(m); AWAKEN(m);
} }
return thread;
} }
/* Add timer event thread. */ /* Add timer event thread. */
struct thread *_thread_add_timer(const struct xref_threadsched *xref, void _thread_add_timer(const struct xref_threadsched *xref,
struct thread_master *m, struct thread_master *m, int (*func)(struct thread *),
int (*func)(struct thread *), void *arg, long timer, struct thread **t_ptr)
void *arg, long timer, struct thread **t_ptr)
{ {
struct timeval trel; struct timeval trel;
@ -1066,15 +1061,14 @@ struct thread *_thread_add_timer(const struct xref_threadsched *xref,
trel.tv_sec = timer; trel.tv_sec = timer;
trel.tv_usec = 0; trel.tv_usec = 0;
return _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr); _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
} }
/* Add timer event thread with "millisecond" resolution */ /* Add timer event thread with "millisecond" resolution */
struct thread *_thread_add_timer_msec(const struct xref_threadsched *xref, void _thread_add_timer_msec(const struct xref_threadsched *xref,
struct thread_master *m, struct thread_master *m,
int (*func)(struct thread *), int (*func)(struct thread *), void *arg, long timer,
void *arg, long timer, struct thread **t_ptr)
struct thread **t_ptr)
{ {
struct timeval trel; struct timeval trel;
@ -1083,24 +1077,21 @@ struct thread *_thread_add_timer_msec(const struct xref_threadsched *xref,
trel.tv_sec = timer / 1000; trel.tv_sec = timer / 1000;
trel.tv_usec = 1000 * (timer % 1000); trel.tv_usec = 1000 * (timer % 1000);
return _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr); _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
} }
/* Add timer event thread with "timeval" resolution */ /* Add timer event thread with "timeval" resolution */
struct thread *_thread_add_timer_tv(const struct xref_threadsched *xref, void _thread_add_timer_tv(const struct xref_threadsched *xref,
struct thread_master *m, struct thread_master *m, int (*func)(struct thread *),
int (*func)(struct thread *), void *arg, struct timeval *tv, struct thread **t_ptr)
void *arg, struct timeval *tv,
struct thread **t_ptr)
{ {
return _thread_add_timer_timeval(xref, m, func, arg, tv, t_ptr); _thread_add_timer_timeval(xref, m, func, arg, tv, t_ptr);
} }
/* Add simple event thread. */ /* Add simple event thread. */
struct thread *_thread_add_event(const struct xref_threadsched *xref, void _thread_add_event(const struct xref_threadsched *xref,
struct thread_master *m, struct thread_master *m, int (*func)(struct thread *),
int (*func)(struct thread *), void *arg, int val, struct thread **t_ptr)
void *arg, int val, struct thread **t_ptr)
{ {
struct thread *thread = NULL; struct thread *thread = NULL;
@ -1128,8 +1119,6 @@ struct thread *_thread_add_event(const struct xref_threadsched *xref,
AWAKEN(m); AWAKEN(m);
} }
return thread;
} }
/* Thread cancellation ------------------------------------------------------ */ /* Thread cancellation ------------------------------------------------------ */

View File

@ -219,26 +219,30 @@ void thread_master_set_name(struct thread_master *master, const char *name);
extern void thread_master_free(struct thread_master *); extern void thread_master_free(struct thread_master *);
extern void thread_master_free_unused(struct thread_master *); extern void thread_master_free_unused(struct thread_master *);
extern struct thread *_thread_add_read_write( extern void _thread_add_read_write(const struct xref_threadsched *xref,
const struct xref_threadsched *xref, struct thread_master *master, struct thread_master *master,
int (*fn)(struct thread *), void *arg, int fd, struct thread **tref); int (*fn)(struct thread *), void *arg,
int fd, struct thread **tref);
extern struct thread *_thread_add_timer( extern void _thread_add_timer(const struct xref_threadsched *xref,
const struct xref_threadsched *xref, struct thread_master *master, struct thread_master *master,
int (*fn)(struct thread *), void *arg, long t, struct thread **tref); int (*fn)(struct thread *), void *arg, long t,
struct thread **tref);
extern struct thread *_thread_add_timer_msec( extern void _thread_add_timer_msec(const struct xref_threadsched *xref,
const struct xref_threadsched *xref, struct thread_master *master, struct thread_master *master,
int (*fn)(struct thread *), void *arg, long t, struct thread **tref); int (*fn)(struct thread *), void *arg,
long t, struct thread **tref);
extern struct thread *_thread_add_timer_tv( extern void _thread_add_timer_tv(const struct xref_threadsched *xref,
const struct xref_threadsched *xref, struct thread_master *master, struct thread_master *master,
int (*fn)(struct thread *), void *arg, struct timeval *tv, int (*fn)(struct thread *), void *arg,
struct thread **tref); struct timeval *tv, struct thread **tref);
extern struct thread *_thread_add_event( extern void _thread_add_event(const struct xref_threadsched *xref,
const struct xref_threadsched *xref, struct thread_master *master, struct thread_master *master,
int (*fn)(struct thread *), void *arg, int val, struct thread **tref); int (*fn)(struct thread *), void *arg, int val,
struct thread **tref);
extern void _thread_execute(const struct xref_threadsched *xref, extern void _thread_execute(const struct xref_threadsched *xref,
struct thread_master *master, struct thread_master *master,

View File

@ -2697,19 +2697,21 @@ static struct thread_master *vty_master;
static void vty_event_serv(enum event event, int sock) static void vty_event_serv(enum event event, int sock)
{ {
struct thread *vty_serv_thread = NULL; struct thread **vty_serv_thread_ptr = NULL;
switch (event) { switch (event) {
case VTY_SERV: case VTY_SERV:
vty_serv_thread = thread_add_read(vty_master, vty_accept, vty_serv_thread_ptr = (struct thread **)vector_get_index(
NULL, sock, NULL); Vvty_serv_thread, sock);
vector_set_index(Vvty_serv_thread, sock, vty_serv_thread); thread_add_read(vty_master, vty_accept, NULL, sock,
vty_serv_thread_ptr);
break; break;
#ifdef VTYSH #ifdef VTYSH
case VTYSH_SERV: case VTYSH_SERV:
vty_serv_thread = thread_add_read(vty_master, vtysh_accept, vty_serv_thread_ptr = (struct thread **)vector_get_index(
NULL, sock, NULL); Vvty_serv_thread, sock);
vector_set_index(Vvty_serv_thread, sock, vty_serv_thread); thread_add_read(vty_master, vtysh_accept, NULL, sock,
vty_serv_thread_ptr);
break; break;
#endif /* VTYSH */ #endif /* VTYSH */
default: default:

View File

@ -2480,10 +2480,6 @@ ospf_router_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc)
return new; return new;
} }
#define OSPF_INTERFACE_TIMER_ON(T, F, V) \
if (!(T)) \
(T) = thread_add_timer(master, (F), oi, (V))
/* Install network-LSA to an area. */ /* Install network-LSA to an area. */
static struct ospf_lsa *ospf_network_lsa_install(struct ospf *ospf, static struct ospf_lsa *ospf_network_lsa_install(struct ospf *ospf,
struct ospf_interface *oi, struct ospf_interface *oi,

View File

@ -223,10 +223,6 @@ struct as_external_lsa {
#define OSPF_LSA_UPDATE_DELAY 2 #define OSPF_LSA_UPDATE_DELAY 2
#define OSPF_LSA_UPDATE_TIMER_ON(T, F) \
if (!(T)) \
(T) = thread_add_timer(master, (F), 0, 2)
#define CHECK_LSA_TYPE_1_TO_5_OR_7(type) \ #define CHECK_LSA_TYPE_1_TO_5_OR_7(type) \
((type == OSPF_ROUTER_LSA) || (type == OSPF_NETWORK_LSA) \ ((type == OSPF_ROUTER_LSA) || (type == OSPF_NETWORK_LSA) \
|| (type == OSPF_SUMMARY_LSA) || (type == OSPF_ASBR_SUMMARY_LSA) \ || (type == OSPF_SUMMARY_LSA) || (type == OSPF_ASBR_SUMMARY_LSA) \

View File

@ -249,8 +249,8 @@ static int zebra_ns_notify_read(struct thread *t)
char buf[BUFSIZ]; char buf[BUFSIZ];
ssize_t len; ssize_t len;
zebra_netns_notify_current = thread_add_read( thread_add_read(zrouter.master, zebra_ns_notify_read, NULL, fd_monitor,
zrouter.master, zebra_ns_notify_read, NULL, fd_monitor, NULL); &zebra_netns_notify_current);
len = read(fd_monitor, buf, sizeof(buf)); len = read(fd_monitor, buf, sizeof(buf));
if (len < 0) { if (len < 0) {
flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ, flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ,
@ -359,8 +359,8 @@ void zebra_ns_notify_init(void)
"NS notify watch: failed to add watch (%s)", "NS notify watch: failed to add watch (%s)",
safe_strerror(errno)); safe_strerror(errno));
} }
zebra_netns_notify_current = thread_add_read( thread_add_read(zrouter.master, zebra_ns_notify_read, NULL, fd_monitor,
zrouter.master, zebra_ns_notify_read, NULL, fd_monitor, NULL); &zebra_netns_notify_current);
} }
void zebra_ns_notify_close(void) void zebra_ns_notify_close(void)