[ECOS] Wake select() with a signal

Roland Caßebohm roland.cassebohm@visionsystems.de
Tue Nov 5 09:29:00 GMT 2002


On Dienstag, 5. November 2002 17:57, Jonathan Larmour wrote:
> Roland Caßebohm wrote:
> > On Dienstag, 5. November 2002 04:46, Jonathan Larmour wrote:
> >>Roland Caßebohm wrote:
> >> > On Friday, 1. November 2002 18:04, Roland Caßebohm wrote:
> >> >> Hi everyone,
> >> >>
> >> >> I want to wake a waiting select by sending a signal to the thread.
> >> >>
> >> >> This does not always work. I think the reason is that the thread in
> >> >> which select() is call is not really sleeping all the time, even
> >> >> though it doesn't return. The pthread_kill() function respectively
> >> >> Cyg_Thread::release() only wakes a thread if the thread is sleeping.
> >> >> That makes sense, but what can I do if I want a waiting select() to
> >> >> return triggered from another thread?
> >> >
> >> > I just changed the select() function that it looks for the asr_pending
> >> > flag before it goes to sleep. I don't really think, that this is the
> >> > right solution, but in my case it works. Now the select() always
> >> > returns with errno=EINTR if the thread receives a signal.
> >>
> >>Hmmm... Before the scheduler lock, the ASR should run. After the
> >> scheduler lock, nothing should be able to trigger an ASR to be
> >> scheduled; in particular nothing should be able to call pthread_kill.
> >> You're not calling pthread_kill from an ISR by any chance are you?
> >
> > I call pthread_kill() from another thread.
>
> Oh well, it was a thought :-).
>
> >>Oh, hold on, is it just that the pthread_kill is happening before the
> >> lock for the first time? If so, then I'm afraid that's tough - you could
> >> just as easily have pthread_kill'd it when the CPU was just making the
> >> call into the select function. From a programmatic point of view, that
> >> can just as easily happen.
> >
> > It could happen before the scheduler is locked for the first time, but
> > allthough if an driver calls cyg_selwakeup() every select() function
> > stops waiting and looks if one of the filedescriptors have a state which
> > the user expected. If not, select() goes to sleep again.
> > In this time the scheduler is not locked, so pthread_kill() can be
> > called.
>
> If the wait is broken by cyg_selwakeup, wait will return 0 and therefore
> EINTR will be returned. Also when the wait returns, the kernel has already
> ensured the scheduler is still locked, hence the need to unlock it before
> returning.
>
> So I think you're worried about the wait returning 1 and going round the
> while (!error) loop again. That shouldn't really happen though in this
> situation.
>
> >>But your signal handler should definitely run
> >>regardless, or are you saying it doesn't do that either?
> >
> > The signal handler doesn't run too. I think this is because by calling
> > selwait.wait() asr_inhibit is set.
> >
> > // Avoid calling ASRs during the following unlock.
> >     self->set_asr_inhibit();
>
> 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();

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

>
> Now I'm talking about what *should* happen, not necessarily what does, if
> you're symptoms suggest otherwise :-).
>
> >> > Does anybody know if the select() systemcall or every other systemcall
> >> > should always return if the thread receives a signal?
> >>
> >>It should return if select() is actually waiting at the time.
> >
> > Shouldn't it allthough return, if it is for any reason not waiting? I
> > think the application just expects, that select() returns if a signal is
> > received.
>
> That needn't be guaranteed, and it's flawed for the app to expect it to be
> guaranteed. The reason is that you could just as easily get the signal
> *just* before entering select(), i.e.:
>
>    FD_SET( fd, &fds );
>                                       <--- signal could happen exactly here
>    err = select( numfds, &fds, NULL, NULL, NULL );
>
>
> 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?

>
> However if select has *already* started waiting, *then* it should wake up
> with EINTR. And I believe that _is_ what you are talking about here anyway.

Yes.

Roland

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



More information about the Ecos-discuss mailing list