I think Alan is referring to the below code.
It's a try lock, so if it doesn't succeed it's just rescheduled for later.

void
EThread::process_event(Event *e, int calling_code)
{
  ink_assert((!e->in_the_prot_queue && !e->in_the_priority_queue));
  MUTEX_TRY_LOCK_FOR(lock, e->mutex, this, e->continuation);
  if (!lock.is_locked()) {
    e->timeout_at = cur_time + DELAY_FOR_RETRY;
    EventQueueExternal.enqueue_local(e);
  } else {
    if (e->cancelled) {
      free_event(e);
      return;
    }
    Continuation *c_temp = e->continuation;
    // Make sure that the contination is locked before calling the handler
    //set_cont_flags(e->continuation->control_flags);
    e->continuation->handleEvent(calling_code, e);

On Tue, Oct 9, 2018 at 2:04 PM Walt Karas <wka...@oath.com.invalid> wrote:

> To what "explicit continuation locking" do you refer?
>
> How does this address the issue that using TSMutexLock() or MutexLock
> in a currently running continuation function (unnecessarily) blocks
> all other events waiting in a thread event queue?  Whereas the
> inability to lock a continuation mutex cause the continuation to be
> requeued at the end of the thread event queue, thus allowing
> succeeding events in the thread's queue to be handled.
> On Tue, Oct 9, 2018 at 3:44 PM Alan Carroll
> <solidwallofc...@oath.com.invalid> wrote:
> >
> > It's a bit more complex than that. One key thing is that if you schedule
> an
> > event for a continuation, when the event handler is called the
> continuation
> > mutex will be locked. Therefore it's rarely the case a plugin needs to
> lock
> > its continuations explicitly. For that reason, simply scheduling handles
> > lock contention without thread blocking.
> >
> > In the core, there is a class, MutexLock, which does the RAII style
> locking.
> >
> > On Tue, Oct 9, 2018 at 2:26 PM Walt Karas <wka...@oath.com.invalid>
> wrote:
> >
> > > In TS, is it important to favor use of continuation mutexes to avoid
> > > thread blocking.  For example, should code like this:
> > >
> > > before();
> > > TSMutexLock(mutex);
> > > critical_section();
> > > TSMutexUnlock(mutex);
> > > after();
> > >
> > > be replaced with code like:
> > >
> > > int contf_after(TSCont, TSEvent, void *)
> > > {
> > >   after();
> > >
> > >   return 0;
> > > }
> > >
> > > int contf_critical_section(TSCont, TSEvent, void *)
> > > {
> > >   critical_section();
> > >
> > >   static TSCont cont_after = TSContCreate(contf_after, nullptr);
> > >
> > >   TSContSchedule(cont_after, 0, TS_THREAD_POOL_DEFAULT);
> > >
> > >   return 0;
> > > }
> > >
> > > // ...
> > >
> > > before();
> > >
> > > static TSCont cont_critical_section =
> > > TSContCreate(contf_critical_section, mutex);
> > >
> > > TSContSchedule(cont_critical_section, 0, TS_THREAD_POOL_DEFAULT);
> > >
> > > // ...
> > >
> > > (This is plugin code but I assume the same principle would apply to
> core
> > > code.)
> > >
> >
> >
> > --
> > *Beware the fisherman who's casting out his line in to a dried up
> riverbed.*
> > *Oh don't try to tell him 'cause he won't believe. Throw some bread to
> the
> > ducks instead.*
> > *It's easier that way. *- Genesis : Duke : VI 25-28
>


-- 
pushkar

Reply via email to