summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/clippy.c4
-rw-r--r--lib/defun_lex.l4
-rw-r--r--lib/northbound_cli.c12
-rw-r--r--lib/thread.c48
4 files changed, 45 insertions, 23 deletions
diff --git a/lib/clippy.c b/lib/clippy.c
index 15cd9d7a4b..c655619b71 100644
--- a/lib/clippy.c
+++ b/lib/clippy.c
@@ -51,7 +51,8 @@ int main(int argc, char **argv)
#if PY_VERSION_HEX >= 0x03040000 /* 3.4 */
Py_SetStandardStreamEncoding("UTF-8", NULL);
#endif
- Py_SetProgramName(wconv(argv[0]));
+ char *name = wconv(argv[0]);
+ Py_SetProgramName(name);
PyImport_AppendInittab("_clippy", command_py_init);
Py_Initialize();
@@ -93,6 +94,7 @@ int main(int argc, char **argv)
for (int i = 1; i < argc; i++)
free(wargv[i - 1]);
#endif
+ free(name);
free(wargv);
return 0;
}
diff --git a/lib/defun_lex.l b/lib/defun_lex.l
index bc5fbd24d9..af506f13d6 100644
--- a/lib/defun_lex.l
+++ b/lib/defun_lex.l
@@ -80,6 +80,8 @@ static void extendbuf(char **what, const char *arg)
}
#define extend(x) extendbuf(&value, x)
+#ifndef __clang_analyzer__
+
%}
ID [A-Za-z0-9_]+
@@ -157,6 +159,8 @@ SPECIAL [(),]
%%
+#endif /* __clang_analyzer__ */
+
static int yylex_clr(char **retbuf)
{
int rv = def_yylex();
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index ad7dad5cb2..1416b758d8 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -600,7 +600,19 @@ void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *root,
(*nb_node->cbs.cli_show_end)(vty, parent);
}
+ /*
+ * There is a possible path in this macro that ends up
+ * dereferencing child->parent->parent. We just null checked
+ * child->parent by checking (ly_iter_next_up(child) != NULL)
+ * above.
+ *
+ * I am not sure whether it is possible for the other
+ * conditions within this macro guarding the problem
+ * dereference to be satisfied when child->parent == NULL.
+ */
+#ifndef __clang_analyzer__
LY_TREE_DFS_END(root, next, child);
+#endif
}
}
diff --git a/lib/thread.c b/lib/thread.c
index e0d734a951..f7f1ed8b7e 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -58,8 +58,7 @@ static int thread_timer_cmp(const struct thread *a, const struct thread *b)
return 0;
}
-DECLARE_HEAP(thread_timer_list, struct thread, timeritem,
- thread_timer_cmp)
+DECLARE_HEAP(thread_timer_list, struct thread, timeritem, thread_timer_cmp)
#if defined(__APPLE__)
#include <mach/mach.h>
@@ -910,31 +909,33 @@ struct thread *_thread_add_read_write(const struct xref_threadsched *xref,
static struct thread *
_thread_add_timer_timeval(const struct xref_threadsched *xref,
struct thread_master *m, int (*func)(struct thread *),
- int type, void *arg, struct timeval *time_relative,
+ void *arg, struct timeval *time_relative,
struct thread **t_ptr)
{
struct thread *thread;
+ struct timeval t;
assert(m != NULL);
- assert(type == THREAD_TIMER);
assert(time_relative);
frrtrace(9, frr_libfrr, schedule_timer, m,
xref->funcname, xref->xref.file, xref->xref.line,
t_ptr, 0, 0, arg, (long)time_relative->tv_sec);
+ /* Compute expiration/deadline time. */
+ monotime(&t);
+ timeradd(&t, time_relative, &t);
+
frr_with_mutex(&m->mtx) {
if (t_ptr && *t_ptr)
/* thread is already scheduled; don't reschedule */
return NULL;
- thread = thread_get(m, type, func, arg, xref);
+ thread = thread_get(m, THREAD_TIMER, func, arg, xref);
frr_with_mutex(&thread->mtx) {
- monotime(&thread->u.sands);
- timeradd(&thread->u.sands, time_relative,
- &thread->u.sands);
+ thread->u.sands = t;
thread_timer_list_add(&m->timer, thread);
if (t_ptr) {
*t_ptr = thread;
@@ -942,7 +943,12 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref,
}
}
- AWAKEN(m);
+ /* The timer list is sorted - if this new timer
+ * might change the time we'll wait for, give the pthread
+ * a chance to re-compute.
+ */
+ if (thread_timer_list_first(&m->timer) == thread)
+ AWAKEN(m);
}
return thread;
@@ -962,8 +968,7 @@ struct thread *_thread_add_timer(const struct xref_threadsched *xref,
trel.tv_sec = timer;
trel.tv_usec = 0;
- return _thread_add_timer_timeval(xref, m, func, THREAD_TIMER, arg,
- &trel, t_ptr);
+ return _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
}
/* Add timer event thread with "millisecond" resolution */
@@ -980,19 +985,17 @@ struct thread *_thread_add_timer_msec(const struct xref_threadsched *xref,
trel.tv_sec = timer / 1000;
trel.tv_usec = 1000 * (timer % 1000);
- return _thread_add_timer_timeval(xref, m, func, THREAD_TIMER, arg,
- &trel, t_ptr);
+ return _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
}
-/* Add timer event thread with "millisecond" resolution */
+/* Add timer event thread with "timeval" resolution */
struct thread *_thread_add_timer_tv(const struct xref_threadsched *xref,
struct thread_master *m,
int (*func)(struct thread *),
void *arg, struct timeval *tv,
struct thread **t_ptr)
{
- return _thread_add_timer_timeval(xref, m, func, THREAD_TIMER, arg, tv,
- t_ptr);
+ return _thread_add_timer_timeval(xref, m, func, arg, tv, t_ptr);
}
/* Add simple event thread. */
@@ -1449,20 +1452,21 @@ static void thread_process_io(struct thread_master *m, unsigned int num)
}
/* Add all timers that have popped to the ready list. */
-static unsigned int thread_process_timers(struct thread_timer_list_head *timers,
+static unsigned int thread_process_timers(struct thread_master *m,
struct timeval *timenow)
{
struct thread *thread;
unsigned int ready = 0;
- while ((thread = thread_timer_list_first(timers))) {
+ while ((thread = thread_timer_list_first(&m->timer))) {
if (timercmp(timenow, &thread->u.sands, <))
- return ready;
- thread_timer_list_pop(timers);
+ break;
+ thread_timer_list_pop(&m->timer);
thread->type = THREAD_READY;
- thread_list_add_tail(&thread->master->ready, thread);
+ thread_list_add_tail(&m->ready, thread);
ready++;
}
+
return ready;
}
@@ -1584,7 +1588,7 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
/* Post timers to ready queue. */
monotime(&now);
- thread_process_timers(&m->timer, &now);
+ thread_process_timers(m, &now);
/* Post I/O to ready queue. */
if (num > 0)