fix strength of reference to a log reader with a thread blocked on it

svn: r11210
This commit is contained in:
Matthew Flatt 2008-08-12 23:54:54 +00:00
parent bd01f9eb88
commit 7347996f66
2 changed files with 21 additions and 3 deletions

View File

@ -2668,6 +2668,7 @@ void update_want_level(Scheme_Logger *logger)
prev = NULL; prev = NULL;
while (queue) { while (queue) {
b = SCHEME_CAR(queue); b = SCHEME_CAR(queue);
b = SCHEME_CAR(b);
lr = (Scheme_Log_Reader *)SCHEME_BOX_VAL(b); lr = (Scheme_Log_Reader *)SCHEME_BOX_VAL(b);
if (lr) { if (lr) {
if (lr->want_level > want_level) if (lr->want_level > want_level)
@ -2834,6 +2835,7 @@ void scheme_log_message(Scheme_Logger *logger, int level, char *buffer, long len
queue = logger->readers; queue = logger->readers;
while (queue) { while (queue) {
b = SCHEME_CAR(queue); b = SCHEME_CAR(queue);
b = SCHEME_CAR(b);
lr = (Scheme_Log_Reader *)SCHEME_BOX_VAL(b); lr = (Scheme_Log_Reader *)SCHEME_BOX_VAL(b);
if (lr) { if (lr) {
if (lr->want_level >= level) { if (lr->want_level >= level) {
@ -3062,7 +3064,14 @@ make_log_reader(int argc, Scheme_Object *argv[])
ch = scheme_make_channel(); ch = scheme_make_channel();
lr->ch = ch; lr->ch = ch;
q = scheme_make_raw_pair(scheme_make_weak_box((Scheme_Object *)lr), logger->readers); /* Pair a weak reference to the reader with a strong reference to the
channel. Channel gets are wrapped to reference the reader. That way,
the link is effectively strong while a thread is sync'd on the
reader. */
q = scheme_make_raw_pair(scheme_make_pair(scheme_make_weak_box((Scheme_Object *)lr),
ch),
logger->readers);
logger->readers = q; logger->readers = q;
*logger->timestamp += 1; *logger->timestamp += 1;
@ -3077,6 +3086,11 @@ log_reader_p(int argc, Scheme_Object *argv[])
: scheme_false); : scheme_false);
} }
static Scheme_Object *id_that_preserves_reader(void *data, int argc, Scheme_Object **argv)
{
return argv[0];
}
static int log_reader_get(Scheme_Object *_lr, Scheme_Schedule_Info *sinfo) static int log_reader_get(Scheme_Object *_lr, Scheme_Schedule_Info *sinfo)
{ {
Scheme_Log_Reader *lr = (Scheme_Log_Reader *)_lr; Scheme_Log_Reader *lr = (Scheme_Log_Reader *)_lr;
@ -3090,7 +3104,11 @@ static int log_reader_get(Scheme_Object *_lr, Scheme_Schedule_Info *sinfo)
scheme_set_sync_target(sinfo, v, NULL, NULL, 0, 0); scheme_set_sync_target(sinfo, v, NULL, NULL, 0, 0);
return 1; return 1;
} else { } else {
scheme_set_sync_target(sinfo, lr->ch, NULL, NULL, 0, 0); Scheme_Object *w;
w = scheme_make_closed_prim(id_that_preserves_reader, lr);
scheme_set_sync_target(sinfo, lr->ch, w, NULL, 0, 0);
return 0; return 0;
} }
} }

View File

@ -2734,7 +2734,7 @@ struct Scheme_Logger {
int want_level; int want_level;
long *timestamp, local_timestamp; /* determines when want_level is up-to-date */ long *timestamp, local_timestamp; /* determines when want_level is up-to-date */
int syslog_level, stderr_level; int syslog_level, stderr_level;
Scheme_Object *readers; /* list of weak boxes */ Scheme_Object *readers; /* list of (cons (make-weak-box <reader>) <channel>) */
}; };
typedef struct Scheme_Log_Reader { typedef struct Scheme_Log_Reader {