Ok great, thanks Greg!
On Fri, Jul 3, 2020 at 1:13 PM Gregory Nutt <spudan...@gmail.com> wrote: > > > I have a few spots in my code where I am doing something, and I'm just > now > > realizing I'm not explicitly sure if it's supported or not. > > > > Here is my question: > > > > Can work_queue be called from within a worker function that uses the same > > work_s struct? > Yes. > > The documentation only says that if there is existing work, it will be > > replaced. But what happens if there is existing work, AND it's currently > > running? > > > > I have a few areas where I'm doing it, and it does seem to be working, > but > > I'm not sure if there are any race conditions or other considerations > that > > I'm not aware of. > > That would be clearer if that read "pending" or "queued" work instead of > "existing" work. The data in the work queue structures is decanted when > the work starts: > > 128 /* Remove the ready-to-execute work from the list */ > 129 > 130 dq_rem((struct dq_entry_s *)work, &wqueue->q); > 131 > 132 /* Extract the work description from the entry (in > case the work > 133 * instance by the re-used after it has been de-queued). > 134 */ > 135 > 136 worker = work->worker; > 137 > 138 /* Check for a race condition where the work may be > nullified > 139 * before it is removed from the queue. > 140 */ > 141 > 142 if (worker != NULL) > 143 { > 144 /* Extract the work argument (before re-enabling > interrupts) */ > 145 > 146 arg = work->arg; > 147 > 148 /* Mark the work as no longer being queued */ > 149 > 150 work->worker = NULL; > 151 > 152 /* Do the work. Re-enable interrupts while the > work is being > 153 * performed... we don't have any idea how long > this will take! > 154 */ > 155 > 156 leave_critical_section(flags); > 157 worker(arg); > 158 > 159 /* Now, unfortunately, since we re-enabled > interrupts we don't > 160 * know the state of the work list and we will > have to start > 161 * back at the head of the list. > 162 */ > 163 > 164 flags = enter_critical_section(); > 165 work = (FAR struct work_s *)wqueue->q.head; > 166 } > > So the work is no longer queued with the worker function executes. > > Greg > > >