Forget what I just wrote. Blame it on a late night. I'll go away and think it
through properly.
G.
Gregory Nicholls wrote:
> Hiya,
> Yeah that'll work, thanks. It's close to what I was planning on adding
> into
> stlib. The main reason I thought it would be good to have in the base code is
> that this is where every thread comes out to play. I do have session context
> in
> my system however the function that issues the interrupt doesn't (yet) have
> access to this context.
> How tough would it be to add the state flags to the stlib thread struct
> and
> hold the state there ???
> An st_defer_interrupt(st_thread_t tid, bool yes) would probably be enough to
> switch it on or off. The idea would be to deliver an EINTR on response to
> st_defer_interrupt(tid, FALSE) if an interrupt had been generated
> during the defer period.
> Comments ??
> G.
>
> Gene Shekhtman wrote:
>
> > Gregory Nicholls wrote:
> >
> > > Hiya,
> > > I'm putting together an SSL server using state-threads. For reasons
> > > I won't go into here I need to be able to interrupt the threads using
> > > st_interrupt(). My problem is that the interrupt could be delivered to
> > > my SSL code at almost anytime, including during an SSL negotiation. I'd
> > > like to be able to 'defer' the receipt of the interrupt while I'm in the
> > > middle of a series of 'must complete' data transfers.
> > > I can't readily see a way of doing this with the current stlib so
> > > I'm thinking of adding suspend/resume logic so I can defer the interrupt
> > > until I'm able to handle it.
> > > My question is, has anyone else run into this issue and if so, how
> > > did you deal with it ??
> >
> > Ah! That's a common problem. Actually, you don't need to modify
> > the ST library to solve it. All you need is two boolean flags in your
> > per session/connection information to correctly maintain the state, e.g.
> >
> > int dont_interrupt; /* Set this flag to 1 while in "must complete" state */
> >
> > int interrupted; /* Set this flag to 1 if session was interrupted */
> >
> > Both flags are initialized to 0.
> >
> > In the code fragment below I assume some sort of "session" data structure
> > where all session/connection information is kept, but you can also store
> > these flags in a per-thread private data.
> >
> > void interrupt_session(session_t *s)
> > {
> > /* Check if session is in the non-interruptible state */
> > if (!s->dont_interrupt)
> > st_interrupt(s->thread);
> > /* Set the flag */
> > s->interrupted = 1;
> > }
> >
> > Now the processing code:
> > ....
> > ....
> > /* First, check if this session was interrupted */
> > if (s->interrupted) {
> > /* Handle interrupt: return error code, abort session/connection/thread,
> > etc. */
> > ....
> > }
> >
> > /* Set "don't interrupt" flag before entering "must complete" section */
> > s->dont_interrupt = 1;
> > /* Enter critical "must complete" section */
> > ....
> > ....
> > /* Done with critical section. Reset "don't interrupt" flag */
> > s->dont_interrupt = 0;
> >
> > /* Now, check again if this session was interrupted while in critical
> > section */
> > if (s->interrupted) {
> > /* Handle interrupt: return error code, abort session/connection/thread,
> > etc. */
> > ....
> > }
> >
> > /* Continue non-critical processing */
> > ....
> >
> > Note that all of the above can be used safely with State Threads because
> > they are non-concurrent and non-preemptive and there is no race condition.
> > You cannot do it with POSIX threads or any other "true" threads.
> > With ST you can always maintain the state with the right number of flags :)
> >
> > --Gene
|