Browse Source

[2861] Pass the callbacks and wake up the thread

Pass the finished callbacks when the tasks are complete and wake up the
remote (main) thread by writing to the socket.
Michal 'vorner' Vaner 11 years ago
parent
commit
3ce8c82c2a
2 changed files with 32 additions and 0 deletions
  1. 4 0
      src/bin/auth/auth_messages.mes
  2. 28 0
      src/bin/auth/datasrc_clients_mgr.h

+ 4 - 0
src/bin/auth/auth_messages.mes

@@ -151,6 +151,10 @@ A separate thread for maintaining data source clients has been started.
 % AUTH_DATASRC_CLIENTS_BUILDER_STOPPED data source builder thread stopped
 The separate thread for maintaining data source clients has been stopped.
 
+% AUTH_DATASRC_CLIENTS_BUILDER_WAKE_ERR failed to wake up main thread: %1
+A low-level error happened when trying to send data to the main thread to wake
+it up. Terminating to prevent inconsistent state and possiblu hang ups.
+
 % AUTH_DATASRC_CLIENTS_SHUTDOWN_ERROR error on waiting for data source builder thread: %1
 This indicates that the separate thread for maintaining data source
 clients had been terminated due to an uncaught exception, and the

+ 28 - 0
src/bin/auth/datasrc_clients_mgr.h

@@ -40,8 +40,11 @@
 
 #include <exception>
 #include <cassert>
+#include <cerrno>
 #include <list>
 #include <utility>
+#include <sys/types.h>
+#include <sys/socket.h>
 
 namespace isc {
 namespace auth {
@@ -531,6 +534,31 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::run() {
                               AUTH_DATASRC_CLIENTS_BUILDER_COMMAND_ERROR).
                         arg(e.what());
                 }
+                if (current_commands.front().callback) {
+                    // Lock the queue
+                    typename MutexType::Locker locker(*queue_mutex_);
+                    callback_queue_->
+                        push_back(current_commands.front().callback);
+                    // Wake up the other end. If it would block, there are data
+                    // and it'll wake anyway.
+                    int result = send(wake_fd_, "w", 1, MSG_DONTWAIT);
+                    if (result == -1 &&
+                        (errno != EWOULDBLOCK && errno != EAGAIN)) {
+                        // Note: the strerror might not be thread safe, as
+                        // subsequent call to it might change the returned
+                        // string. But that is unlikely and strerror_r is
+                        // not portable and we are going to terminate anyway,
+                        // so that's better than nothing.
+                        //
+                        // Also, this error handler is not tested. It should
+                        // be generally impossible to happen, so it is hard
+                        // to trigger in controlled way.
+                        LOG_FATAL(auth_logger,
+                                  AUTH_DATASRC_CLIENTS_BUILDER_WAKE_ERR).
+                            arg(strerror(errno));
+                        std::terminate();
+                    }
+                }
                 current_commands.pop_front();
             }
         }