More Efficient Thread Client Context layout RRS feed

  • Question

  • Hi,

    Following most of the similar IOCP worker pool models for socket servers which many have a similar basic framework from the POP3 example in the SDK, the user-defined completion key allocated struct PCLIENT_CONTENT lpCC contains nature C types and pointers used to contain client data and its passed as a parameter to static connection/session handler functions.  The lpCC is associated with the i/o port and socket and the handlers must use this container for any specific session allocation/deallocation of data.

    Off hand, after playing with this for many months, this seems to be very efficient, lower overhead, etc and now that I seem to have a good understanding of I/O completion ports and how the OS uses it, I am now trying to fit this into our current server protocols using a classic 1 thread per socket client/server design.

    My question is will I lose efficiency, i.e. more non-pool pages, more page swapping,  if I instantiate class instances that will contain its own data members as well in the CLIENT_CONTEXT allocation?

    For example, in all the IOCP examples, they have a basic container like so:

    typedef struct _CLIENT_CONTEXT {
      SOCKET      ClientSocket;   // Connection socket
      PVOID      SessionContext;  // App defined block
      LAST_CLIENT_IO  LastClientIo;   // Action
      DWORD      BytesReadSoFar;
      OVERLAPPED    Overlapped;
      CHAR       Buffer[8*1024];
    and I want to see if I change this to:
    typedef struct _CLIENT_CONTEXT {
      CSessionHandler *SessionContext;  // App defined
      LAST_CLIENT_IO  LastClientIo;   // Action
      DWORD      BytesReadSoFar;
      OVERLAPPED    Overlapped;
      CHAR       Buffer[8*1024];

    I ask because currently in our non-IOCP version,  for each new clientSocket = accept(listenSocket, NULL, NULL)  connection,  we start a new self-deleting thread class instance of CSessionHandler()

    new CSessionHandler(new CSocketIO(clientSocket));

    A socket class wrapper for clientSocket is instantiated and this is passed to the new CSessionHandler(CSocketIO *sio) which is a sub-class of a CThread Class I have.  When the session ends, the class self-deletes itself.

    So I want to know if I modify CSessionHandler to a non-thread version and use this in the PCLIENT_CONTEXT worker thread container,  even if it works well, if its less efficient?

    Its a design question of either a) revamping my server applications to a new set of data + static functions versus b) reusability (as much as possible) a set of classes long engineered with operational features that are already in place.

    The state machine for our server protocols has years of operational knowledge and its all self contained as sub classes of abstract CSessionHandler which only wants two parts to work: a connection interface and a event dispatch array of class member functions  So in reality for any one of our protocol servers, i.e. SMTP, POP3, FTP, NNTP, etc, it would be:

    new CSMTPSessionHandler(new CSocketIO(clientSocket));

    new CPOP3SessionHandler(new CSocketIO(clientSocket));

    new CFTPSessionHandler(new CSocketIO(clientSocket));

    new CNNTPSessionHandler(new CSocketIO(clientSocket));

    I actually posted a public version at codeproject.com in 2003 of this class at 

    CSPServer, State-based Protocol Server Class - CodeProject

    But its a classic 1 thread per socket client/server model, not a more efficient IOCP model and that is what I am changing it to since all our protocols use internal version of CSPServer class posted at codeproject.com,  a version with SSL support, backend central server channel events (force disconnect, PCI required session management features, application server-script pcode integration, etc).

    So there is a lot of operational overhead, features that would have to be recoded.

    I guess I can explore this and see if this less efficient, but it seems that DATA + STATIC functions will be efficient. But how much more?

    I also presume this is a C++ question too in how the class object is created with either inline or static functions and although I am not up to par with "todays" template (Not yesterdays) designs, in my mind this seems to be something that may part of the answer?

    Overall, I am trying to do a "plug and play" transparent change to an IOCP using the same or altered existing classes without losing too much efficient you get from a DATA + STATIC function IOCP model.




    Hector Santos, http://www.santronics.com
    Via Wildcat! Live Exchange NNTP Gateway http://opensite.winserver.com
    Friday, December 31, 2010 6:47 PM