Fix potential deadlock in signal_set implementation.
diff --git a/asio/include/asio/detail/impl/signal_set_service.ipp b/asio/include/asio/detail/impl/signal_set_service.ipp
index 8764f5b..9c260c3 100644
--- a/asio/include/asio/detail/impl/signal_set_service.ipp
+++ b/asio/include/asio/detail/impl/signal_set_service.ipp
@@ -161,14 +161,22 @@
   switch (fork_ev)
   {
   case asio::io_service::fork_prepare:
-    reactor_.deregister_internal_descriptor(
-        state->read_descriptor_, reactor_data_);
-    state->fork_prepared_ = true;
+    {
+      int read_descriptor = state->read_descriptor_;
+      state->fork_prepared_ = true;
+      lock.unlock();
+      reactor_.deregister_internal_descriptor(read_descriptor, reactor_data_);
+    }
     break;
   case asio::io_service::fork_parent:
-    state->fork_prepared_ = false;
-    reactor_.register_internal_descriptor(reactor::read_op,
-        state->read_descriptor_, reactor_data_, new pipe_read_op);
+    if (state->fork_prepared_)
+    {
+      int read_descriptor = state->read_descriptor_;
+      state->fork_prepared_ = false;
+      lock.unlock();
+      reactor_.register_internal_descriptor(reactor::read_op,
+          read_descriptor, reactor_data_, new pipe_read_op);
+    }
     break;
   case asio::io_service::fork_child:
     if (state->fork_prepared_)
@@ -176,10 +184,12 @@
       asio::detail::signal_blocker blocker;
       close_descriptors();
       open_descriptors();
+      int read_descriptor = state->read_descriptor_;
       state->fork_prepared_ = false;
+      lock.unlock();
+      reactor_.register_internal_descriptor(reactor::read_op,
+          read_descriptor, reactor_data_, new pipe_read_op);
     }
-    reactor_.register_internal_descriptor(reactor::read_op,
-        state->read_descriptor_, reactor_data_, new pipe_read_op);
     break;
   default:
     break;
@@ -480,8 +490,10 @@
 
 #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__)
   // Register for pipe readiness notifications.
+  int read_descriptor = state->read_descriptor_;
+  lock.unlock();
   service->reactor_.register_internal_descriptor(reactor::read_op,
-      state->read_descriptor_, service->reactor_data_, new pipe_read_op);
+      read_descriptor, service->reactor_data_, new pipe_read_op);
 #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__)
 }
 
@@ -494,8 +506,11 @@
   {
 #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__)
     // Disable the pipe readiness notifications.
+    int read_descriptor = state->read_descriptor_;
+    lock.unlock();
     service->reactor_.deregister_descriptor(
-        state->read_descriptor_, service->reactor_data_, false);
+        read_descriptor, service->reactor_data_, false);
+    lock.lock();
 #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__)
 
     // Remove service from linked list of all services.