8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:43:03 +01:00

Fixed bug CORE-1457: Server crashes attempting to deliver events for the just disconnected session.

Part one - AV in events code
This commit is contained in:
hvlad 2007-09-13 13:28:05 +00:00
parent 314c7e2e42
commit cc42c8c462
2 changed files with 22 additions and 10 deletions

View File

@ -852,17 +852,19 @@ static void delete_session(SLONG session_id)
SES session = (SES) SRQ_ABS_PTR(session_id);
#ifdef MULTI_THREAD
USHORT kill_anyway = 0; /* Kill session despite session delivering. */
/* delay gives up control for 250ms, so a 40 iteration timeout is a
* up to 10 second wait for session to finish delivering its message.
*/
while (session->ses_flags & SES_delivering && (++kill_anyway != 40)) {
// if session currently delivered events delay its deletion until deliver ends
if (session->ses_flags & SES_delivering)
{
session->ses_flags |= SES_purge;
// give a chance for delivering thread to detect SES_purge flag we just set
release();
THREAD_EXIT();
THREAD_SLEEP(250);
THREAD_SLEEP(100);
THREAD_ENTER();
acquire();
session = (SES) SRQ_ABS_PTR(session_id);
return;
}
#endif
@ -913,8 +915,9 @@ static AST_TYPE deliver(void* arg)
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
process->prb_flags &= ~PRB_pending;
srq* que2;
SRQ_LOOP(process->prb_sessions, que2) {
srq* que2 = SRQ_NEXT(process->prb_sessions);
while (que2 != &process->prb_sessions)
{
SES session = (SES) ((UCHAR *) que2 - OFFSET(SES, ses_sessions));
#ifdef MULTI_THREAD
session->ses_flags |= SES_delivering;
@ -931,14 +934,22 @@ static AST_TYPE deliver(void* arg)
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
session = (SES) SRQ_ABS_PTR(session_offset);
que2 = (srq *) SRQ_ABS_PTR(que2_offset);
flag = true;
flag = !(session->ses_flags & SES_purge);
break;
}
}
}
#ifdef MULTI_THREAD
session->ses_flags &= ~SES_delivering;
if (session->ses_flags & SES_purge)
{
que2 = SRQ_NEXT((*que2));
delete_session(SRQ_REL_PTR(session));
break;
}
else
#endif
que2 = SRQ_NEXT((*que2));
}
release();

View File

@ -117,6 +117,7 @@ struct ses {
typedef ses *SES;
const int SES_delivering = 1; /* Watcher thread is delivering an event */
const int SES_purge = 2; // delete session after delivering an event
/* Event block */