]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
try to call write() immediately. If it works, we're fine
authorAlan T. DeKok <aland@freeradius.org>
Tue, 11 Jul 2017 13:08:33 +0000 (09:08 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 11 Jul 2017 13:08:56 +0000 (09:08 -0400)
This avoids a lot of overhead in updating the event list,
and doing lots of callbacks.

src/modules/rlm_radius/rlm_radius.c

index 1a3e053e15b74615c4ae809f4e304ced2d729d66..6c69404d437334d3226f7bd69dd0e37c2405cc3f 100644 (file)
@@ -264,8 +264,9 @@ static void mod_radius_conn_writable(UNUSED fr_event_list_t *el, UNUSED int sock
 
                rad_assert(link->waiting = false);
 
-               // @todo - if this returns EWOULDBLOCK, stop
-               // @todo - if this returns "too many requests", stop.  But the caller should have checked...
+               /*
+                *      Write to the socket.
+                */
                rcode = c->inst->client_io->write(link->request, link->request_io_ctx, c->client_io_ctx);
 
                /*
@@ -661,8 +662,38 @@ static int CC_HINT(nonnull) mod_add(rlm_radius_t *inst, rlm_radius_connection_t
         *      If there are no pending writes, enable the write
         *      callback.  It will wake up and write the packets to
         *      the socket.
+        *
+        *      We have no packets in the queue.  Try calling write().
+        *      If it succeeds, we're good, and we can avoid updating
+        *      the event list along with many callbacks and lots of
+        *      overhead.
         */
        if (!c->pending) {
+               int rcode;
+
+               rcode = c->inst->client_io->write(link->request, link->request_io_ctx, c->client_io_ctx);
+               if (rcode < 0) {
+                       talloc_free(link);
+                       return -1;
+               }
+
+               /*
+                *      It was successfully written to the socket.
+                *      Update the various timers, etc.
+                */
+               if (rcode == 1) {
+                       link->time_sent = fr_time();
+                       fr_dlist_remove(&link->entry);
+                       fr_dlist_insert_head(&c->sent, &link->entry);
+                       link->waiting = true;
+                       c->num_outstanding++;
+                       return 1;
+               }
+
+               /*
+                *      We couldn't write it, so leave the request on
+                *      the pending queue.
+                */
                c->pending = true;
                mod_radius_fd_active(c);
        }