s3:smbd: convert aio to use tevent_signal
[metze/samba/wip.git] / source3 / smbd / aio.c
index 8beed0744c17e106194236dd426a42c47331a0e8..4ce43c95e80f2cd04bf5b84e4be5d90f80d8d530 100644 (file)
@@ -19,6 +19,7 @@
 */
 
 #include "includes.h"
+#include "smbd/globals.h"
 
 #if defined(WITH_AIO)
 
@@ -53,8 +54,6 @@ struct aio_extra {
 static int handle_aio_read_complete(struct aio_extra *aio_ex);
 static int handle_aio_write_complete(struct aio_extra *aio_ex);
 
-static struct aio_extra *aio_list_head;
-
 static int aio_extra_destructor(struct aio_extra *aio_ex)
 {
        DLIST_REMOVE(aio_list_head, aio_ex);
@@ -109,63 +108,6 @@ static struct aio_extra *find_aio_ex(uint16 mid)
  We can have these many aio buffers in flight.
 *****************************************************************************/
 
-static int aio_pending_size;
-static sig_atomic_t signals_received;
-static int outstanding_aio_calls;
-static uint16 *aio_pending_array;
-
-/****************************************************************************
- Signal handler when an aio request completes.
-*****************************************************************************/
-
-void aio_request_done(uint16_t mid)
-{
-       if (signals_received < aio_pending_size) {
-               aio_pending_array[signals_received] = mid;
-               signals_received++;
-       }
-       /* Else signal is lost. */
-}
-
-static void signal_handler(int sig, siginfo_t *info, void *unused)
-{
-       aio_request_done(info->si_value.sival_int);
-       sys_select_signal(RT_SIGNAL_AIO);
-}
-
-/****************************************************************************
- Is there a signal waiting ?
-*****************************************************************************/
-
-bool aio_finished(void)
-{
-       return (signals_received != 0);
-}
-
-/****************************************************************************
- Initialize the signal handler for aio read/write.
-*****************************************************************************/
-
-void initialize_async_io_handler(void)
-{
-       struct sigaction act;
-
-       aio_pending_size = lp_maxmux();
-       aio_pending_array = SMB_MALLOC_ARRAY(uint16, aio_pending_size);
-       SMB_ASSERT(aio_pending_array != NULL);
-
-       ZERO_STRUCT(act);
-       act.sa_sigaction = signal_handler;
-       act.sa_flags = SA_SIGINFO;
-       sigemptyset( &act.sa_mask );
-       if (sigaction(RT_SIGNAL_AIO, &act, NULL) != 0) {
-                DEBUG(0,("Failed to setup RT_SIGNAL_AIO handler\n"));
-        }
-
-       /* the signal can start off blocked due to a bug in bash */
-       BlockSignals(False, RT_SIGNAL_AIO);
-}
-
 /****************************************************************************
  Set up an aio request from a SMBreadX call.
 *****************************************************************************/
@@ -579,57 +521,47 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
  Returns non-zero errno if fail or zero if all ok.
 *****************************************************************************/
 
-int process_aio_queue(void)
+void smbd_aio_complete_mid(unsigned int mid)
 {
-       int i;
+       files_struct *fsp = NULL;
+       struct aio_extra *aio_ex = find_aio_ex(mid);
        int ret = 0;
 
-       BlockSignals(True, RT_SIGNAL_AIO);
-
-       DEBUG(10,("process_aio_queue: signals_received = %d\n",
-                 (int)signals_received));
-       DEBUG(10,("process_aio_queue: outstanding_aio_calls = %d\n",
-                 outstanding_aio_calls));
+       DEBUG(10,("smbd_aio_complete_mid: mid[%u]\n", mid));
 
-       if (!signals_received) {
-               BlockSignals(False, RT_SIGNAL_AIO);
-               return 0;
+       if (!aio_ex) {
+               DEBUG(3,("smbd_aio_complete_mid: Can't find record to "
+                        "match mid %u.\n", mid));
+               srv_cancel_sign_response(mid);
+               return;
        }
 
-       /* Drain all the complete aio_reads. */
-       for (i = 0; i < signals_received; i++) {
-               uint16 mid = aio_pending_array[i];
-               files_struct *fsp = NULL;
-               struct aio_extra *aio_ex = find_aio_ex(mid);
-
-               if (!aio_ex) {
-                       DEBUG(3,("process_aio_queue: Can't find record to "
-                                "match mid %u.\n", (unsigned int)mid));
-                       srv_cancel_sign_response(mid);
-                       continue;
-               }
+       fsp = aio_ex->fsp;
+       if (fsp == NULL) {
+               /* file was closed whilst I/O was outstanding. Just
+                * ignore. */
+               DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst "
+                          "aio outstanding (mid[%u]).\n", mid));
+               srv_cancel_sign_response(mid);
+               return;
+       }
 
-               fsp = aio_ex->fsp;
-               if (fsp == NULL) {
-                       /* file was closed whilst I/O was outstanding. Just
-                        * ignore. */
-                       DEBUG( 3,( "process_aio_queue: file closed whilst "
-                                  "aio outstanding.\n"));
-                       srv_cancel_sign_response(mid);
-                       continue;
-               }
+       if (!handle_aio_completed(aio_ex, &ret)) {
+               return;
+       }
 
-               if (!handle_aio_completed(aio_ex, &ret)) {
-                       continue;
-               }
+       TALLOC_FREE(aio_ex);
+}
 
-               TALLOC_FREE(aio_ex);
-       }
+static void smbd_aio_signal_handler(struct tevent_context *ev_ctx,
+                                   struct tevent_signal *se,
+                                   int signum, int count,
+                                   void *_info, void *private_data)
+{
+       siginfo_t *info = (siginfo_t *)_info;
+       unsigned int mid = (unsigned int)info->si_value.sival_int;
 
-       outstanding_aio_calls -= signals_received;
-       signals_received = 0;
-       BlockSignals(False, RT_SIGNAL_AIO);
-       return ret;
+       smbd_aio_complete_mid(mid);
 }
 
 /****************************************************************************
@@ -761,19 +693,28 @@ void cancel_aio_by_fsp(files_struct *fsp)
        }
 }
 
-#else
-bool aio_finished(void)
-{
-       return False;
-}
+/****************************************************************************
+ Initialize the signal handler for aio read/write.
+*****************************************************************************/
 
 void initialize_async_io_handler(void)
 {
+       aio_signal_event = tevent_add_signal(smbd_event_context(),
+                                            smbd_event_context(),
+                                            RT_SIGNAL_AIO, SA_SIGINFO,
+                                            smbd_aio_signal_handler,
+                                            NULL);
+       if (!aio_signal_event) {
+               exit_server("Failed to setup RT_SIGNAL_AIO handler");
+       }
+
+       /* tevent supports 100 signal with SA_SIGINFO */
+       aio_pending_size = 100;
 }
 
-int process_aio_queue(void)
+#else
+void initialize_async_io_handler(void)
 {
-       return False;
 }
 
 bool schedule_aio_read_and_X(connection_struct *conn,
@@ -801,4 +742,7 @@ int wait_for_aio_completion(files_struct *fsp)
 {
        return ENOSYS;
 }
+
+void smbd_aio_complete_mid(unsigned int mid);
+
 #endif