From 0e5441d8161042493fcfdacaeed2a770f1f7285c Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 22 Jul 2010 13:08:02 +0200 Subject: [PATCH] don't use object sharing inside I/O threads, as a fix for a well known instability of VM introduced with the new object sharing code --- src/object.c | 11 +++++++++-- src/redis.c | 1 + src/redis.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/object.c b/src/object.c index 772637ce..25567e2a 100644 --- a/src/object.c +++ b/src/object.c @@ -213,8 +213,15 @@ robj *tryObjectEncoding(robj *o) { /* Check if we can represent this string as a long integer */ if (isStringRepresentableAsLong(s,&value) == REDIS_ERR) return o; - /* Ok, this object can be encoded */ - if (value >= 0 && value < REDIS_SHARED_INTEGERS) { + /* Ok, this object can be encoded... + * + * Can I use a shared object? Only if the object is inside a given + * range and if this is the main thread, sinc when VM is enabled we + * have the constraint that I/O thread should only handle non-shared + * objects, in order to avoid race conditions (we don't have per-object + * locking). */ + if (value >= 0 && value < REDIS_SHARED_INTEGERS && + pthread_equal(pthread_self(),server.mainthread)) { decrRefCount(o); incrRefCount(shared.integers[value]); return shared.integers[value]; diff --git a/src/redis.c b/src/redis.c index 86536b43..433eae37 100644 --- a/src/redis.c +++ b/src/redis.c @@ -760,6 +760,7 @@ void initServer() { signal(SIGPIPE, SIG_IGN); setupSigSegvAction(); + server.mainthread = pthread_self(); server.devnull = fopen("/dev/null","w"); if (server.devnull == NULL) { redisLog(REDIS_WARNING, "Can't open /dev/null: %s", server.neterr); diff --git a/src/redis.h b/src/redis.h index 4ff83620..d5fabc2d 100644 --- a/src/redis.h +++ b/src/redis.h @@ -327,6 +327,7 @@ struct sharedObjectsStruct { /* Global server state structure */ struct redisServer { + pthread_t mainthread; int port; int fd; redisDb *db; -- 2.45.2