diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-06-29 09:30:09 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-06-29 09:30:09 -0600 |
commit | 1deaf2a9634576bf0e0f35a24911c3f22215fbd2 (patch) | |
tree | cfc63769fd41a0e4417e2a723d79e4ba8fb6f077 /nuttx/libc | |
parent | 02bad8e430f112e7f0bac29f52861c7048cb2bbe (diff) | |
download | px4-nuttx-1deaf2a9634576bf0e0f35a24911c3f22215fbd2.tar.gz px4-nuttx-1deaf2a9634576bf0e0f35a24911c3f22215fbd2.tar.bz2 px4-nuttx-1deaf2a9634576bf0e0f35a24911c3f22215fbd2.zip |
Fixes for networking and tiny webserver from Max
Diffstat (limited to 'nuttx/libc')
-rw-r--r-- | nuttx/libc/wqueue/work_thread.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/nuttx/libc/wqueue/work_thread.c b/nuttx/libc/wqueue/work_thread.c index 285f7183c..c0474ad69 100644 --- a/nuttx/libc/wqueue/work_thread.c +++ b/nuttx/libc/wqueue/work_thread.c @@ -148,26 +148,44 @@ static void work_process(FAR struct wqueue_s *wqueue) */ worker = work->worker; - arg = work->arg; - /* Mark the work as no longer being queued */ + /* Check for a race condition where the work may be nullified + * before it is removed from the queue. + */ - work->worker = NULL; + if (worker != NULL) + { + /* Extract the work argument (before re-enabling interrupts) */ - /* Do the work. Re-enable interrupts while the work is being - * performed... we don't have any idea how long that will take! - */ + arg = work->arg; - irqrestore(flags); - worker(arg); + /* Mark the work as no longer being queued */ - /* Now, unfortunately, since we re-enabled interrupts we don't - * know the state of the work list and we will have to start - * back at the head of the list. - */ + work->worker = NULL; + + /* Do the work. Re-enable interrupts while the work is being + * performed... we don't have any idea how long that will take! + */ + + irqrestore(flags); + worker(arg); - flags = irqsave(); - work = (FAR struct work_s *)wqueue->q.head; + /* Now, unfortunately, since we re-enabled interrupts we don't + * know the state of the work list and we will have to start + * back at the head of the list. + */ + + flags = irqsave(); + work = (FAR struct work_s *)wqueue->q.head; + } + else + { + /* Cancelled.. Just move to the next work in the list with + * interrupts still disabled. + */ + + work = (FAR struct work_s *)work->dq.flink; + } } else { |