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
>
>
>

Reply via email to