]> git.sesse.net Git - stockfish/commitdiff
Fix a (theoretical) race leading to a crash
authorMarco Costalba <mcostalba@gmail.com>
Fri, 6 Apr 2012 14:22:02 +0000 (15:22 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 6 Apr 2012 14:30:41 +0000 (15:30 +0100)
After we release the SplitPoint lock the master, suppose
is main thread, can safely return and if a "quit" command
is pending, main thread exits and associated Thread object
is freed. So when we access master->is_searching a crash
occurs.

I have never found such a race that is of course very rare
becuase assumes that from lock releasing we go to sleep for
a time long enough for the main thread to end the search and
return. But you can never know, and anyhow a race is a race.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/search.cpp

index 371144086898bf417e16af7d17a261e8b5849870..eaba6c6d83b96fee4797696a6c606c3648bddfe6 100644 (file)
@@ -1826,7 +1826,6 @@ void Thread::idle_loop(SplitPoint* sp_master) {
 
           Stack ss[MAX_PLY_PLUS_2];
           Position pos(*sp->pos);
 
           Stack ss[MAX_PLY_PLUS_2];
           Position pos(*sp->pos);
-          Thread* master = sp->master;
 
           memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
           (ss+1)->sp = sp;
 
           memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
           (ss+1)->sp = sp;
@@ -1848,17 +1847,18 @@ void Thread::idle_loop(SplitPoint* sp_master) {
           sp->slavesMask &= ~(1ULL << idx);
           sp->nodes += pos.nodes_searched();
 
           sp->slavesMask &= ~(1ULL << idx);
           sp->nodes += pos.nodes_searched();
 
-          // After releasing the lock we cannot access anymore any SplitPoint
-          // related data in a reliably way becuase it could have been released
-          // under our feet by the sp master.
-          lock_release(sp->lock);
-
           // Wake up master thread so to allow it to return from the idle loop in
           // case we are the last slave of the split point.
           if (   Threads.use_sleeping_threads()
           // Wake up master thread so to allow it to return from the idle loop in
           // case we are the last slave of the split point.
           if (   Threads.use_sleeping_threads()
-              && this != master
-              && !master->is_searching)
-              master->wake_up();
+              && this != sp->master
+              && !sp->master->is_searching)
+              sp->master->wake_up();
+
+          // After releasing the lock we cannot access anymore any SplitPoint
+          // related data in a safe way becuase it could have been released under
+          // our feet by the sp master. Also accessing other Thread objects is
+          // unsafe because if we are exiting there is a chance are already freed.
+          lock_release(sp->lock);
       }
   }
 }
       }
   }
 }