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
|