Files
sics/nread.w
koennecke 361ee9ebea - Reworked the connection object and the IO system
- Reworked the support for TRICS
- Added a second generation motor
2009-02-03 08:05:39 +00:00

146 lines
7.0 KiB
OpenEdge ABL

\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 introducing 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 appropriate 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 appropriate 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 running 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.
In January 2009 a new asynchronous I/O structure was devised. This makes most of
NetReader obsolete. However, it was decided to keep the old structure for the
time being. A new function, NetReadInstallANETPort was added to install server
ports for the new system.
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);
/*--------------------------------------------------------------------------*/
int NetReadInstallANETPort(pNetRead self, eNRType eType, int iPort);
@}
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
@}