]> git.saurik.com Git - redis.git/commitdiff
don't use object sharing inside I/O threads, as a fix for a well known instability...
authorantirez <antirez@gmail.com>
Thu, 22 Jul 2010 11:08:02 +0000 (13:08 +0200)
committerantirez <antirez@gmail.com>
Thu, 22 Jul 2010 11:08:02 +0000 (13:08 +0200)
src/object.c
src/redis.c
src/redis.h

index 772637ce050d46940140ab7bbbebd4064ec381bf..25567e2acf36daa4ac780382a1d01394efc8b3b1 100644 (file)
@@ -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];
index 86536b4375a0ec0938da0b6b8691a62194efb819..433eae37eb937d873508b71848b95c32e953a297 100644 (file)
@@ -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);
index 4ff8362074fc1a7e0610510004d8cb6ae172e667..d5fabc2d226a404173362091b80bdc5eeadbe1ee 100644 (file)
@@ -327,6 +327,7 @@ struct sharedObjectsStruct {
 
 /* Global server state structure */
 struct redisServer {
+    pthread_t mainthread;
     int port;
     int fd;
     redisDb *db;