[PATCH] Add thread safety to socket_wrapper

Andreas Schneider asn at samba.org
Thu Feb 22 11:03:11 UTC 2018

On Thursday, 22 February 2018 11:46:36 CET Volker Lendecke wrote:
> On Thu, Feb 22, 2018 at 11:28:30AM +0100, Andreas Schneider via samba-
technical wrote:
> > the attached patchset adds thread safety support to socket_wrapper. It is
> > the ground work for fd passing to test multichannel and smbdirect in
> > selftest.
> > 
> > It would be great to get additional review. If I don't hear anything till
> > next week Wednesday I'm going to push it.
> Not that it's relevant for the cwrap project, still my 2ct:
> What's the point of SOCKET_INFO_GET_REFCOUNT? It's even more
> characters in source code. Also, SOCKET_INFO_GET hides the reference
> to a global variable. Why? These macros make the code harder to read,
> at least for me. Macros can have their place, but what's the reasoning
> here?

Hi Volker,

we implemented it that way, that in future steps, we just have to change 
SOCKET_INFO_GET() and not modify the complete source code again and again. We 
wanted to keep changes minimal if possible. Yes, currently it is a global 
variable but that will change. I hope our TODO list (appended at the end) 
helps you to understand the master plan behind it.

Your input is as always welcome :-)


1) untangle fds from socket info:

   - have a list of socket_info_fd structures
     referencing socket_info structure.
   - No list of socket_info any more.
   - refcount of users in socket_info

   ==> done

2) create an array of socket_info structures.

   - fixed length SOCKET_WRAPPER_MAX_SOCKETS (e.g)
     default value can be overridden by env var.
   - array allocated (calloc) at initialization.
   - socket_info_fd structure has index into array
     instead of pointer to struct.
   - treating close: when last reference goes away
     then the entry (idx) needs to be marked as a
     free/unused entry: refcount == 0 is the signal
   - when creating a new socket, need to find an
     unused element (first approach: iterate)

   ==> done

   possible optimization
   - use a more efficient way of tracking free entries.
     possibly a freelist:
     - first_free variable
     - next_free structure in the socket_info items

   ==> done

3) Use pthread mutexes on structures to make swrap
   ( socket_info, socket_info_fds, free-list )

4) Put the socket_info array and the free-list
   into shared memory (of some kind) between
   swrap processes.

   - approach:
     - use mmapped file
     - use pthread robust mutexes to protect access
       from multiple processes

5) Implementation of fd-passing:

   - Open a pipe, and add the receiving end of
     the pipe to the fds-array of the sendmsg call.

   - After the actual sendmsg call in swrap, write an array
     `fd_indexes` of integers into the pipe, the length being
     the length of the original fds array with
     fd_indexes[i] = find_socket_info_index(fds[i]),
     the index in the sockets array at which the socket_info for
     fds[i] is located.
     Put '-1' if this fd is not treated by socket-wrapper.
     After writing the list of indexes, close the pipe.

   - The receiver of sendmsg reads the array `fd_indexes` of indexes
     from the pipe and closes it. For each position i, where the
     index that is not -1, create a socket_fd structure with the
     fi.fd = fds[i] (where fds is the received fd array) and
     fi.si_index = fd_indexes[i]. Bump si.refcount.

Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             asn at samba.org

More information about the samba-technical mailing list