On Thursday, November 04, 2010 5:49:22 pm Matthew Fleming wrote: > On Thu, Nov 4, 2010 at 2:22 PM, John Baldwin <jhb_at_freebsd.org> wrote: > > On Thursday, November 04, 2010 4:15:16 pm Hans Petter Selasky wrote: > >> I think that if a task is currently executing, then there should be a drain > >> method for that. I.E. two methods: One to stop and one to cancel/drain. Can > >> you implement this? > > > > I agree, this would also be consistent with the callout_*() API if you had > > both "stop()" and "drain()" methods. > > Here's my proposed code. Note that this builds but is not yet tested. > > > Implement a taskqueue_cancel(9), to cancel a task from a queue. > > Requested by: hps > Original code: jeff > MFC after: 1 week > > > http://people.freebsd.org/~mdf/bsd-taskqueue-cancel.diff For FreeBSD taskqueue_cancel() should return EBUSY, not -EBUSY. However, I would prefer that it follow the semantics of callout_stop() and return true if it stopped the task and false otherwise. The Linux wrapper for taskqueue_cancel() can convert the return value. I'm not sure I like reusing the memory allocation flags (M_NOWAIT / M_WAITOK) for this blocking flag. In the case of callout(9) we just have two functions that pass an internal boolean to the real routine (callout_stop() and callout_drain() are wrappers for _callout_stop_safe()). It is a bit unfortunate that taskqueue_drain() already exists and has different semantics than callout_drain(). It would have been nice to have the two APIs mirror each other instead. Hmm, I wonder if the blocking behavior cannot safely be provided by just doing: if (!taskqueue_cancel(queue, task, M_NOWAIT) taskqueue_drain(queue, task); If that works ok (I think it does), I would rather have taskqueue_cancel() always be non-blocking. Even though there is a "race" where the task could be rescheduled by another thread in between cancel and drain, the race still exists since if the task could be scheduled between the two, it could also be scheduled just before the call to taskqueue_cancel() (in which case a taskqueue_cancel(queue, task, M_WAITOK) would have blocked to wait for it matching the taskqueue_drain() above). The caller still always has to provide synchronization for preventing a task's execution outright via their own locking. -- John BaldwinReceived on Fri Nov 05 2010 - 12:02:49 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:08 UTC