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