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
|