feisty meow concerns codebase  2.140
socket_minder.h
Go to the documentation of this file.
1 #ifndef SOCKET_MINDER_CLASS
2 #define SOCKET_MINDER_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : socket_minder *
7 * Author : Chris Koeritz *
8 * *
9 * Purpose: *
10 * *
11 * Provides a base for activities that tend a communication element called *
12 * a socket. Sockets are numerically identified, but the number is only *
13 * unique on the specific medium of interest. The socket minder also tracks *
14 * the send and receive status and buffers for the socket. *
15 * *
16 *******************************************************************************
17 * Copyright (c) 1999-$now By Author. This program is free software; you can *
18 * redistribute it and/or modify it under the terms of the GNU General Public *
19 * License as published by the Free Software Foundation; either version 2 of *
20 * the License or (at your option) any later version. This is online at: *
21 * http://www.fsf.org/copyleft/gpl.html *
22 * Please send any updates to: fred@gruntose.com *
23 \*****************************************************************************/
24 
25 #include <basis/contracts.h>
26 #include <processes/mailbox.h>
27 #include <processes/post_office.h>
28 
29 namespace sockets {
30 
31 // forward declarations.
32 class raw_socket;
33 class socket_data;
34 class socket_data_amorph;
35 class socket_minder_prompter;
36 class tcpip_stack;
37 
39 
40 class socket_minder : public virtual basis::root_object
41 {
42 public:
43  socket_minder(processes::post_office &post, int parent_route, int event_type,
44  int message);
45  // the "parent_route" is where we will send asynchronous tcpip events,
46  // which will be stored in the "post". the "event_type" is the identifier
47  // for the OS_events that will be generated and the "message" is the id
48  // stored inside the events.
49 
50  virtual ~socket_minder();
51 
52  void disengage();
53  // this method should be invoked before the socket_minder is destroyed.
54  // it ensures that the object is released from background event delivery.
55 
56  DEFINE_CLASS_NAME("socket_minder");
57 
58  basis::astring text_form() const;
59  // returns a dump of the minder's current state.
60 
61  socket_data *lock_socket_data(int socket);
62  // locates the data for the "socket" specified. the list is left locked
63  // unless NULL_POINTER is returned.
64 
65  void unlock_socket_data(socket_data *to_unlock);
66  // unlocks the list of socket data again and zeroes "to_unlock".
67 
68  bool add_socket_data(int socket, bool server, int server_socket,
69  bool connected_mode, bool connection_pending);
70  // adds a new record for the "socket" which is possibly a "server". only
71  // fails with false when the socket is already listed. the
72  // "connected_mode" should be true if this socket is connection-oriented.
73 
74  bool remove_socket_data(int socket);
75  // rips out the data held for "socket". only fails with false when the
76  // record couldn't be found to delete.
77 
78  bool set_connection_pending(int socket, bool pending);
79  // changes the state of pending connection for the "socket". if "pending"
80  // is true, then the socket is either trying to accept connections or it
81  // is trying to connect. if false, then it is no longer attempting this.
82 
83  bool is_connection_pending(int socket);
84  // returns the current state of pending-ness for the "socket". false could
85  // also mean the socket cannot be found.
86 
87  bool register_interest(int socket, int interests);
88  // sets the events to watch for on the "socket" from the "interests".
89  // these are values merged bitwise from the socket_interests enum. they
90  // must be interpreted appropriately by different kinds of transports. the
91  // evaluate_interest() method must be over-ridden for the interests to
92  // actually be implemented. registering with "interests" as zero will
93  // reset all interests to be... disinterested.
94 
95  virtual bool evaluate_interest(socket_data &to_examine);
96  // this can be over-ridden by a derived socket minder to handle needs
97  // besides simple bsd socket management. but the implementation provided
98  // here will generate events upon occurrence of a registered interest on
99  // the socket. an event letter is sent to the appropriate parent id
100  // containing the event that was noticed. true is returned if "to_examine"
101  // was successfully evaluated. any changes made to the socket's data are
102  // recorded. since the socket minder is locked during this upcall, it is
103  // important not to cause any deadlocks by careless additional locking.
104 
105  int get_pending_server();
106  // returns a non-zero socket number if a server socket was accepted on
107  // and is waiting to be processed.
108 
109  bool zap_pending_server(int socket);
110  // removes the "socket" from the pending servers list, if present.
111 
112  void put_pending_server(int to_put, bool at_head);
113  // stores a pending server socket into the list, either since it just got
114  // noticed as an accepted socket or because it cannot be processed yet.
115 
116  void get_sockets(basis::int_array &read_sox, basis::int_array &write_sox,
117  basis::int_array &pending) const;
118  // reports the set of sockets that this minder is handling in "read_sox",
119  // since we assume any socket could be checked for pending received data.
120  // if there is pending data to send, then they are put into the "write_sox"
121  // to be checked for writability. the existing contents of the lists are
122  // not cleared, so this function can be used to join the lists of several
123  // socket_minders together.
124 
125  bool owns_socket(int socket) const;
126  // returns true if this minder owns the "socket" in question.
127 
128  void push_sends(socket_data &to_poke, int states);
129  void push_receives(socket_data &to_poke, int states);
130  // if the state is right, we'll try our hand at grabbing some data. if the
131  // "states" include SI_READABLE, then we'll try and receive on the socket
132  // in push_receives. if they include SI_WRITABLE, then we'll send out
133  // pending data in push_sends.
134 
135  bool handle_pending_connecters(socket_data &to_peek);
136  // returns true if the socket "to_peek" is awaiting a connection and we
137  // have prompted that activity appropriately. false means that this
138  // socket is not awaiting a connection.
139 
140  void snoozy_select();
141  // goes into a select on all applicable sockets and waits until one
142  // of them has activity before waking up.
143 
144 private:
145  processes::post_office &_post; // manages recycling of letters for us.
146  int _parent_route; // the identifier of our parent in the postal system.
147  int _event_type; // what we generate OS_events as.
148  basis::mutex *_lock; // maintains list integrity.
149  socket_data_amorph *_socket_list; // the table of information per socket.
150  raw_socket *_socks; // lets us access the OS's socket subsystem.
151  tcpip_stack *_stack; // provides tcpip protocol stack.
152  int _message; // the message type stored inside the generated OS_events.
153  structures::int_set *_pending_sox; // accepted servers that are waiting to be processed.
154  socket_minder_prompter *_prompter; // snoozes on sockets awaiting activity.
155 
156  void fire_event(int to_fire, int at_whom, basis::un_int parm1, basis::un_int parm2);
157 
158  // not implemented:
159  socket_minder(const socket_minder &sm);
160  socket_minder &operator =(const socket_minder &sm);
161 };
162 
163 } //namespace.
164 
165 #endif
166 
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
A simple object that wraps a templated array of ints.
Definition: array.h:275
Manages a collection of mailboxes and implements delivery routes for mail.
Definition: post_office.h:35
void get_sockets(basis::int_array &read_sox, basis::int_array &write_sox, basis::int_array &pending) const
bool is_connection_pending(int socket)
bool handle_pending_connecters(socket_data &to_peek)
void put_pending_server(int to_put, bool at_head)
bool set_connection_pending(int socket, bool pending)
bool remove_socket_data(int socket)
bool register_interest(int socket, int interests)
virtual bool evaluate_interest(socket_data &to_examine)
bool zap_pending_server(int socket)
socket_data * lock_socket_data(int socket)
void push_sends(socket_data &to_poke, int states)
bool add_socket_data(int socket, bool server, int server_socket, bool connected_mode, bool connection_pending)
DEFINE_CLASS_NAME("socket_minder")
void push_receives(socket_data &to_poke, int states)
basis::astring text_form() const
bool owns_socket(int socket) const
void unlock_socket_data(socket_data *to_unlock)
socket_minder(processes::post_office &post, int parent_route, int event_type, int message)
Helpful functions for interacting with TCP/IP stacks.
Definition: tcpip_stack.h:38
A simple object that wraps a templated set of ints.
Definition: set.h:156
unsigned int un_int
Abbreviated name for unsigned integers.
Definition: definitions.h:62
Provides access to the operating system's socket methods.
Definition: base_address.h:26