Initial revision
This commit is contained in:
139
nread.w
Normal file
139
nread.w
Normal file
@ -0,0 +1,139 @@
|
||||
\subsection{The Network Reader}
|
||||
The network readers task is to read incoming messages for the SICS server.
|
||||
These may come in four main forms.
|
||||
\begin{itemize}
|
||||
\item connection requests
|
||||
\item commands
|
||||
\item interrupts
|
||||
through a command channel
|
||||
\item interrupt messages on the UDP port.
|
||||
\end{itemize}
|
||||
A prior
|
||||
version of SICS had a select system call for each of these cases. It was
|
||||
found, that the code spent most of its time in the select system call
|
||||
thus intrdoducing a major performance problem.
|
||||
|
||||
The select system call can handle more then one file descriptor in one call.
|
||||
This is exactly what this module handles. It does a global select on
|
||||
all open sockets and forwards any pending data to approriate handlers.
|
||||
This scheme brought a drastic
|
||||
performance improvement.
|
||||
|
||||
Each of the messages to SICS is handled
|
||||
differently:
|
||||
|
||||
A connection request will be validated, a new connection object will be
|
||||
created and a new task for this connection object will be started.
|
||||
|
||||
A command will be placed in the apropriate command stack for the task
|
||||
belonging to this connection to work on in a later stage. The netreader will
|
||||
also take care that all commands are complete, this is the terminator
|
||||
\verb+\n+ or \verb+\r+ has been sent.
|
||||
|
||||
Both forms of interrupt will be interpreted and a suitable signal
|
||||
will be sent to all runing tasks if the interrupt request is valid.
|
||||
|
||||
In order to perform his tasks the network reader needs to maintain a list of
|
||||
all open sockets and their types. Additionally it needs to know about the
|
||||
SICS tasker.
|
||||
|
||||
The early version of SICS only supported connections on a plain
|
||||
socket. This feauture is not used any more in favour of the Telnet
|
||||
option described below. However, as this may be used to transport
|
||||
binary data, the obsolete code has not been removed.
|
||||
|
||||
Support for the internet TCP/IP standard telnet protocoll has been added in
|
||||
January 1998. Telnet things need to be handled differently, therefore two
|
||||
more socket types have been defined: A telnet listen socket on which
|
||||
requests for telnet connections are listened for, and a telnet command
|
||||
socket which actually process the telnet messages.
|
||||
|
||||
Support for user sockets was added in February 1998. User sockets provides a
|
||||
primitive interface to the network readers monitoring functions. This is
|
||||
part of a solution to one problem which can occur in SICS: The whole server
|
||||
is blocked if one of the serial devices is slow in responding. User sockets
|
||||
now provide a method for client code to register a socket for monitoring
|
||||
with the network reader and find out if data is pending at it. This support
|
||||
is provided by the functions: NetReadRegisterUserSocket,
|
||||
NetReadRemoveUserSocket, NetReadReadable and NetReadResetUser described
|
||||
below. NetReadWait4Data is a special wait function which waits for data to
|
||||
come in on a user socket. This function is problematic with dynamically
|
||||
creates and deleted objects such as environment device objects. Its use is
|
||||
therefore no longer recommended.
|
||||
|
||||
Thus the interface looks like this:
|
||||
|
||||
@d nrint @{
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef struct __netreader *pNetRead;
|
||||
typedef enum {naccept, command, udp, user, taccept, tcommand} eNRType;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pNetRead CreateNetReader(pServer pServ, int iPasswdTimeout,
|
||||
int iReadTimeout);
|
||||
void DeleteNetReader(void *pData);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int NetReadRegister(pNetRead self, mkChannel *pSock, eNRType eType,
|
||||
SConnection *pCon);
|
||||
int NetReadRegisterUserSocket(pNetRead self, int iSocket);
|
||||
int NetReadRemove(pNetRead self, mkChannel *pSock);
|
||||
int NetReadRemoveUserSocket(pNetRead self, int iSocket);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int NetReaderTask(void *pReader);
|
||||
void NetReaderSignal(void *pUser, int iSignal, void *pSigData);
|
||||
int NetReadWait4Data(pNetRead self, int iSocket);
|
||||
int NetReadReadable(pNetRead self, int iSocket);
|
||||
int NetReadResetUser(pNetRead self, int iSocket);
|
||||
@}
|
||||
|
||||
This starts off with the definition of a data type for the net reader and an
|
||||
enum which denotes the possible types of connections.
|
||||
\begin{description}
|
||||
\item[CreateNetReader] sets a new net reader up. Only parameter is a pointer
|
||||
to the task manager to use while creating new connections. iPasswdTimeout
|
||||
is the period in which a client is expected to send his userid/password
|
||||
pair. iReadTimeout is the time to wait on the select statement for a
|
||||
channel to become readable. Both time values are specified in milliseconds.
|
||||
\item[DeleteNetReader] deletes the net reader and all its data structures.
|
||||
Must be called in order to free all memory.
|
||||
\item[NetReadRegister] register the channel pSock of type eType with the net
|
||||
reader self. The parameter pData will only be interpreted for connections
|
||||
of type command. It must point to the command stack belonging to the
|
||||
connection which registers this socket.
|
||||
\item[NetReadRegisterUserSocket] registers a socket from within SICS foth
|
||||
the network reader. The client code to this module may then find out with a
|
||||
call to NetReadReadable if data is pending on this socket. This a
|
||||
convenience wrapper to NetReadRegister.
|
||||
\item[NetReadRemove] removes the socket pSock from the net reader. This must
|
||||
be done when closing the socket, otherwise the net reader will continue
|
||||
checking for pending data on this socket.
|
||||
\item[NetReadRemoveUserSocket] removes a user socket from
|
||||
monitoring. Again, this is a vonvenience wrapper around NetReadRemove.
|
||||
\item[NetReaderTask] is the net reader task function which will be
|
||||
registered with the task manager. This function builds the select
|
||||
mask, does the select and forwards incoming data to the appropriate
|
||||
handler functions. These are not documented here, as they are file
|
||||
static function in nread.c.
|
||||
\item[NetReaderSignal] is the signal handler for the net reader. It
|
||||
just stops the NetReaderTask when the SICS server is run down.
|
||||
\item[NetReadReadable] returns 1 if data is pending at the user socket or 0
|
||||
if not.
|
||||
\item[NetReadResetUser] resets a user socket to not readable.
|
||||
\end{description}
|
||||
|
||||
@o nread.h @{
|
||||
/*------------------------------------------------------------------------
|
||||
N E T R E A D E R
|
||||
|
||||
This module will check for pending requests to the SICS server and
|
||||
initiate apropriate actions.
|
||||
|
||||
Mark Koenencke, September 1997
|
||||
|
||||
copyright: see copyright.h
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef SICSNETREADER
|
||||
#define SICSNETREADER
|
||||
@<nrint@>
|
||||
#endif
|
||||
@}
|
Reference in New Issue
Block a user