Patchwork [Ada] Avoid raising an exception in Connect_Socket with timeout

login
register
mail settings
Submitter Arnaud Charlet
Date April 11, 2013, 12:36 p.m.
Message ID <20130411123659.GA30299@adacore.com>
Download mbox | patch
Permalink /patch/235724/
State New
Headers show

Comments

Arnaud Charlet - April 11, 2013, 12:36 p.m.
This change replaces a call to a thick socket operation binding that uses
an exception to report an expected condition (return with EINPROGRESS
error) with a thin call reporting the same information through a return
value and errno setting, to avoid an unnecessary exception raise.

Tested on x86_64-pc-linux-gnu, committed on trunk

2013-04-11  Thomas Quinot  <quinot@adacore.com>

	* g-socket.adb (Connect_Socket, timeout version): Call
	underlying connect operation directly, not through the 2-argument
	Connect_Socket thick binding, in order to avoid raising a junk
	exception for the EINPROGRESS return.

Patch

Index: g-socket.adb
===================================================================
--- g-socket.adb	(revision 197743)
+++ g-socket.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                     Copyright (C) 2001-2012, AdaCore                     --
+--                     Copyright (C) 2001-2013, AdaCore                     --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -200,6 +200,12 @@ 
    --  Raise Constraint_Error if Fd is less than 0 or greater than or equal to
    --  FD_SETSIZE, on platforms where fd_set is a bitmap.
 
+   function Connect_Socket
+     (Socket : Socket_Type;
+      Server : Sock_Addr_Type) return C.int;
+   pragma Inline (Connect_Socket);
+   --  Underlying implementation for the Connect_Socket procedures
+
    --  Types needed for Datagram_Socket_Stream_Type
 
    type Datagram_Socket_Stream_Type is new Root_Stream_Type with record
@@ -662,11 +668,10 @@ 
    -- Connect_Socket --
    --------------------
 
-   procedure Connect_Socket
+   function Connect_Socket
      (Socket : Socket_Type;
-      Server : Sock_Addr_Type)
+      Server : Sock_Addr_Type) return C.int
    is
-      Res : C.int;
       Sin : aliased Sockaddr_In;
       Len : constant C.int := Sin'Size / 8;
 
@@ -681,17 +686,19 @@ 
         (Sin'Unchecked_Access,
          Short_To_Network (C.unsigned_short (Server.Port)));
 
-      Res := C_Connect (C.int (Socket), Sin'Address, Len);
+      return C_Connect (C.int (Socket), Sin'Address, Len);
+   end Connect_Socket;
 
-      if Res = Failure then
+   procedure Connect_Socket
+     (Socket : Socket_Type;
+      Server : Sock_Addr_Type)
+   is
+   begin
+      if Connect_Socket (Socket, Server) = Failure then
          Raise_Socket_Error (Socket_Errno);
       end if;
    end Connect_Socket;
 
-   --------------------
-   -- Connect_Socket --
-   --------------------
-
    procedure Connect_Socket
      (Socket   : Socket_Type;
       Server   : Sock_Addr_Type;
@@ -719,19 +726,16 @@ 
       Req := (Name => Non_Blocking_IO, Enabled => True);
       Control_Socket (Socket, Request => Req);
 
-      --  Start operation (non-blocking), will raise Socket_Error with
-      --  EINPROGRESS.
+      --  Start operation (non-blocking), will return Failure with errno set
+      --  to EINPROGRESS.
 
-      begin
-         Connect_Socket (Socket, Server);
-      exception
-         when E : Socket_Error =>
-            if Resolve_Exception (E) = Operation_Now_In_Progress then
-               null;
-            else
-               raise;
-            end if;
-      end;
+      Res := Connect_Socket (Socket, Server);
+      if Res = Failure then
+         Conn_Err := Socket_Errno;
+         if Conn_Err /= SOSC.EINPROGRESS then
+            Raise_Socket_Error (Conn_Err);
+         end if;
+      end if;
 
       --  Wait for socket to become available for writing