socket_minder.h

Go to the documentation of this file.
00001 #ifndef SOCKET_MINDER_CLASS
00002 #define SOCKET_MINDER_CLASS
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : socket_minder                                                     *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *  Purpose:                                                                   *
00010 *                                                                             *
00011 *    Provides a base for activities that tend a communication element called  *
00012 *  a socket.  Sockets are numerically identified, but the number is only      *
00013 *  unique on the specific medium of interest.  The socket minder also tracks  *
00014 *  the send and receive status and buffers for the socket.                    *
00015 *                                                                             *
00016 *******************************************************************************
00017 * Copyright (c) 1999-$now By Author.  This program is free software; you can  *
00018 * redistribute it and/or modify it under the terms of the GNU General Public  *
00019 * License as published by the Free Software Foundation; either version 2 of   *
00020 * the License or (at your option) any later version.  This is online at:      *
00021 *     http://www.fsf.org/copyleft/gpl.html                                    *
00022 * Please send any updates to: fred@gruntose.com                               *
00023 \*****************************************************************************/
00024 
00025 #include "sockets_dll.h"
00026 
00027 #include <basis/object_base.h>
00028 
00029 // forward.
00030 class mailbox;
00031 class post_office;
00032 class raw_socket;
00033 class socket_data;
00034 class socket_data_amorph;
00035 class socket_minder_prompter;
00036 class tcpip_stack;
00037 
00039 
00040 class SOCKETS_CLASS_STYLE socket_minder : public virtual object_base
00041 {
00042 public:
00043   socket_minder(post_office &post, int parent_route, int event_type,
00044           int message);
00045     // the "parent_route" is where we will send asynchronous tcpip events,
00046     // which will be stored in the "post".  the "event_type" is the identifier
00047     // for the OS_events that will be generated and the "message" is the id
00048     // stored inside the events.
00049 
00050   virtual ~socket_minder();
00051 
00052   void disengage();
00053     // this method should be invoked before the socket_minder is destroyed.
00054     // it ensures that the object is released from background event delivery.
00055 
00056   IMPLEMENT_CLASS_NAME("socket_minder");
00057 
00058   istring text_form() const;
00059     // returns a dump of the minder's current state.
00060 
00061   socket_data *lock_socket_data(int socket);
00062     // locates the data for the "socket" specified.  the list is left locked
00063     // unless NIL is returned.
00064 
00065   void unlock_socket_data(socket_data *to_unlock);
00066     // unlocks the list of socket data again and zeroes "to_unlock".
00067 
00068   bool add_socket_data(int socket, bool server, int server_socket,
00069           bool connected_mode, bool connection_pending);
00070     // adds a new record for the "socket" which is possibly a "server".  only
00071     // fails with false when the socket is already listed.  the
00072     // "connected_mode" should be true if this socket is connection-oriented.
00073 
00074   bool remove_socket_data(int socket);
00075     // rips out the data held for "socket".  only fails with false when the
00076     // record couldn't be found to delete.
00077 
00078   bool set_connection_pending(int socket, bool pending);
00079     // changes the state of pending connection for the "socket".  if "pending"
00080     // is true, then the socket is either trying to accept connections or it
00081     // is trying to connect.  if false, then it is no longer attempting this.
00082 
00083   bool is_connection_pending(int socket);
00084     // returns the current state of pending-ness for the "socket".  false could
00085     // also mean the socket cannot be found.
00086 
00087   bool register_interest(int socket, int interests);
00088     // sets the events to watch for on the "socket" from the "interests".
00089     // these are values merged bitwise from the socket_interests enum.  they
00090     // must be interpreted appropriately by different kinds of transports.  the
00091     // evaluate_interest() method must be over-ridden for the interests to
00092     // actually be implemented.  registering with "interests" as zero will
00093     // reset all interests to be... disinterested.
00094 
00095   virtual bool evaluate_interest(socket_data &to_examine);
00096     // this can be over-ridden by a derived socket minder to handle needs
00097     // besides simple bsd socket management.  but the implementation provided
00098     // here will generate events upon occurrence of a registered interest on
00099     // the socket.  an event letter is sent to the appropriate parent id
00100     // containing the event that was noticed.  true is returned if "to_examine"
00101     // was successfully evaluated.  any changes made to the socket's data are
00102     // recorded.  since the socket minder is locked during this upcall, it is
00103     // important not to cause any deadlocks by careless additional locking.
00104 
00105   int get_pending_server();
00106     // returns a non-zero socket number if a server socket was accepted on
00107     // and is waiting to be processed.
00108 
00109   bool zap_pending_server(int socket);
00110     // removes the "socket" from the pending servers list, if present.
00111 
00112   void put_pending_server(int to_put, bool at_head);
00113     // stores a pending server socket into the list, either since it just got
00114     // noticed as an accepted socket or because it cannot be processed yet.
00115 
00116   void get_sockets(int_array &read_sox, int_array &write_sox,
00117           int_array &pending) const;
00118     // reports the set of sockets that this minder is handling in "read_sox",
00119     // since we assume any socket could be checked for pending received data.
00120     // if there is pending data to send, then they are put into the "write_sox"
00121     // to be checked for writability.  the existing contents of the lists are
00122     // not cleared, so this function can be used to join the lists of several
00123     // socket_minders together.
00124 
00125   bool owns_socket(int socket) const;
00126     // returns true if this minder owns the "socket" in question.
00127 
00128   void push_sends(socket_data &to_poke, int states);
00129   void push_receives(socket_data &to_poke, int states);
00130     // if the state is right, we'll try our hand at grabbing some data.  if the
00131     // "states" include SI_READABLE, then we'll try and receive on the socket
00132     // in push_receives.  if they include SI_WRITABLE, then we'll send out
00133     // pending data in push_sends.
00134 
00135   bool handle_pending_connecters(socket_data &to_peek);
00136     // returns true if the socket "to_peek" is awaiting a connection and we
00137     // have prompted that activity appropriately.  false means that this
00138     // socket is not awaiting a connection.
00139 
00140   void snoozy_select();
00141     // goes into a select on all applicable sockets and waits until one
00142     // of them has activity before waking up.
00143 
00144 private:
00145   post_office &_post;  // manages recycling of letters for us.
00146   int _parent_route;  // the identifier of our parent in the postal system.
00147   int _event_type;  // what we generate OS_events as.
00148   mutex *_lock;  // maintains list integrity.
00149   socket_data_amorph *_socket_list;  // the table of information per socket.
00150   raw_socket *_socks;  // lets us access the OS's socket subsystem.
00151   tcpip_stack *_stack;  // provides tcpip protocol stack.
00152   int _message;  // the message type stored inside the generated OS_events.
00153   int_set *_pending_sox;  // accepted servers that are waiting to be processed.
00154   socket_minder_prompter *_prompter;  // snoozes on sockets awaiting activity.
00155 
00156   void fire_event(int to_fire, int at_whom, u_int parm1, u_int parm2);
00157 
00158   // not implemented:
00159   socket_minder(const socket_minder &sm);
00160   socket_minder &operator =(const socket_minder &sm);
00161 };
00162 
00163 #endif
00164 

Generated on Fri Nov 21 04:29:16 2008 for HOOPLE Libraries by  doxygen 1.5.1