This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Wake select() with a signal


Roland Caßebohm <roland.cassebohm@visionsystems.de> writes:

> On Dienstag, 5. November 2002 17:57, Jonathan Larmour wrote:
> > Ah, now that seems more interesting. But still, the signal should cause
> > the thread to be released, the ASR inhibit then gets cleared, and the
> > signal handler should be called when wait() unlocks the scheduler.
> 
> The ASR inhibit gets cleared after unlocking the scheduler:
> 
>     // Avoid calling ASRs during the following unlock.
>     self->set_asr_inhibit();
> 
>     // Unlock the scheduler and switch threads
>     Cyg_Scheduler::unlock_reschedule();
> 
>     // Allow ASRs again
>     self->clear_asr_inhibit();

But wait_inner() also subsequently calls mx->lock() to relock the
mutex, so any pending ASRs will be called during the unlock in there.

However, in select() the FILEIO_ENTRY() and FILEIO_RETURN_VALUE()
macros contain calls to cyg_posix_function_start() and
cyg_posix_function_finish() which inhibit and uninhibit ASRs around
the whole function, so any manipulation that wait_inner() does is
superflous. The finish function deliberately blips the scheduler lock
so that any pending ASRs will be deferred until select() exits.

> 
> So the ASR inhibit will not be cleared if nobody wakes the thread again.
>

This is true, but is also true in the signal-just-before-select case
too. 

> > So it's a problem that doesn't need to be solved because an app that tried
> > to rely on it would be broken anyway.
> 
> Yes, I think that could be a problem for my application too. This is 
> definitely not a problem of eCos, but do you know how can I solve this?

This is a general failing of the design of the select() and signal
mechanisms in Unix. They were invented when all processes were single
threaded. With the introduction of threads, there is the potential for
a race condition, between signal delivery and the decision to call
select().

In Unix I suppose one way of fixing this would have been to add a pipe
to the set of read FDs and have the other thread write to that to wake
the select() -- you probably don't need to use a signal at all. We do
not have pipes in eCos, but a loop-back TCP socket would probably do
the same thing.

The POSIX-200X standard has added a pselect() call, which takes an
additional signal mask argument, specifically to allow this race
condition to be eliminated.


-- 
Nick Garnett - eCos Kernel Architect
http://www.eCosCentric.com/

--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]