(********************************************************************) (* *) (* poll.s7i Support for pollData and the poll function *) (* Copyright (C) 2011 Thomas Mertes *) (* *) (* This file is part of the Seed7 Runtime Library. *) (* *) (* The Seed7 Runtime Library is free software; you can *) (* redistribute it and/or modify it under the terms of the GNU *) (* Lesser General Public License as published by the Free Software *) (* Foundation; either version 2.1 of the License, or (at your *) (* option) any later version. *) (* *) (* The Seed7 Runtime Library is distributed in the hope that it *) (* will be useful, but WITHOUT ANY WARRANTY; without even the *) (* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *) (* PURPOSE. See the GNU Lesser General Public License for more *) (* details. *) (* *) (* You should have received a copy of the GNU Lesser General *) (* Public License along with this program; if not, write to the *) (* Free Software Foundation, Inc., 51 Franklin Street, *) (* Fifth Floor, Boston, MA 02110-1301, USA. *) (* *) (********************************************************************) include "sockbase.s7i"; include "socket.s7i"; const integer: POLLNOTHING is 0; const integer: POLLIN is 1; const integer: POLLOUT is 2; const integer: POLLINOUT is 3; (** * Type to manage sockets and corresponding event checks and findings. * ''PollData'' maintains input (checkedEvents) and output (eventFindings) * of the function [[#poll(inout_pollData)|poll]]. ''PollData'' contains * a set of sockets. For every [[socket]] the checkedEvents and the * eventFindings are maintained. The checkedEvents determine, which * events (POLLIN, POLLOUT, or POLLINOUT) should be checked by * [[#poll(inout_pollData)|poll]]. ''Poll'' determines the events found * and stores them as eventFindings. ''PollData'' provides also an * iterator, which can be used to iterate over checkedEvents and * eventFindings. *) const type: pollData is newtype; IN_PARAM_IS_REFERENCE(pollData); const proc: destroy (ref pollData: aValue) is action "POL_DESTR"; const proc: (ref pollData: dest) ::= (ref pollData: source) is action "POL_CREATE"; const proc: (inout pollData: dest) := (ref pollData: source) is action "POL_CPY"; const func pollData: _GENERATE_EMPTY_POLL_DATA (in file: aFile) is action "POL_EMPTY"; const pollData: (attr pollData) . value is _GENERATE_EMPTY_POLL_DATA(STD_NULL); (** * Clears ''pData''. * All [[socket|sockets]] and all events are removed from ''pData'' and * the iterator is reset, such that ''hasNext'' returns FALSE. *) const proc: clear (inout pollData: pData) is action "POL_CLEAR"; (** * Add ''eventsToCheck'' for ''aSocket'' to ''pData''. * ''EventsToCheck'' can have one of the following values: * * POLLIN check if data can be read from the corresponding socket. * * POLLOUT check if data can be written to the corresponding socket. * * POLLINOUT check if data can be read or written (POLLIN or POLLOUT). * @param pollData Poll data to which the event checks are added. * @param aSocket Socket for which the events should be checked. * @param eventsToCheck Events to be added to the checkedEvents * field of ''pData''. * @param fileObj File to be returned, if the iterator returns * files in ''pData''. * @exception RANGE_ERROR Illegal value for ''eventsToCheck''. * @exception MEMORY_ERROR An out of memory situation occurred. * @exception FILE_ERROR A limit of the operating system was reached. *) const proc: addCheck (inout pollData: pData, in PRIMITIVE_SOCKET: aSocket, in integer: eventsToCheck, in file: aFile) is action "POL_ADD_CHECK"; const proc: addCheck (inout pollData: pData, in socket: aSocket, in integer: eventsToCheck) is func begin addCheck(pData, aSocket.sock, eventsToCheck, aSocket); end func; (** * Add ''eventsToCheck'' for ''aFile'' to ''pData''. * ''EventsToCheck'' can have one of the following values: * * POLLIN check if data can be read from the corresponding [[socket]]. * * POLLOUT check if data can be written to the corresponding socket. * * POLLINOUT check if data can be read or written (POLLIN or POLLOUT). * @param pollData Poll data to which the event checks are added. * @param aFile File for which the events should be checked. * @param eventsToCheck Events to be added to the checkedEvents * field of ''pData''. * @exception RANGE_ERROR Illegal value for ''eventsToCheck''. * @exception MEMORY_ERROR An out of memory situation occurred. * @exception FILE_ERROR A limit of the operating system was reached. *) const proc: addCheck (inout pollData: pData, in file: aFile, in integer: eventsToCheck) is DYNAMIC; (** * Remove ''eventsToCheck'' for ''aSocket'' from ''pData''. * ''EventsToCheck'' can have one of the following values: * * POLLIN check if data can be read from the corresponding [[socket]]. * * POLLOUT check if data can be written to the corresponding socket. * * POLLINOUT check if data can be read or written (POLLIN or POLLOUT). * @param pollData Poll data from which the event checks are removed. * @param aSocket Socket for which the events should not be checked. * @param eventsToCheck Events to be removed from the checkedEvents * field of ''pData''. * @exception RANGE_ERROR Illegal value for ''eventsToCheck''. *) const proc: removeCheck (inout pollData: pData, in PRIMITIVE_SOCKET: aSocket, in integer: eventsToCheck) is action "POL_REMOVE_CHECK"; const proc: removeCheck (inout pollData: pData, in socket: aSocket, in integer: eventsToCheck) is func begin removeCheck(pData, aSocket.sock, eventsToCheck); end func; (** * Remove ''eventsToCheck'' for ''aFile'' from ''pData''. * ''EventsToCheck'' can have one of the following values: * * POLLIN check if data can be read from the corresponding [[socket]]. * * POLLOUT check if data can be written to the corresponding socket. * * POLLINOUT check if data can be read or written (POLLIN or POLLOUT). * @param pollData Poll data from which the event checks are removed. * @param aFile File for which the events should not be checked. * @param eventsToCheck Events to be removed from the checkedEvents * field of ''pData''. * @exception RANGE_ERROR Illegal value for ''eventsToCheck''. *) const proc: removeCheck (inout pollData: pData, in file: aFile, in integer: eventsToCheck) is DYNAMIC; (** * Return the checkedEvents field from ''pData'' for ''aSocket''. * The [[#poll(inout_pollData)|poll]] function uses the checkedEvents * as input. The following checkedEvents can be returned: * * POLLNOTHING no data can be read or written. * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read and written (POLLIN and POLLOUT). * @return POLLNOTHING, POLLIN, POLLOUT or POLLINOUT, depending on * the events added and removed for ''aSocket' with * ''addCheck'' and ''removeCheck''. *) const func integer: getCheck (inout pollData: pData, in PRIMITIVE_SOCKET: aSocket) is action "POL_GET_CHECK"; const func integer: getCheck (inout pollData: pData, in socket: aSocket) is return getCheck(pData, aSocket.sock); (** * Return the checkedEvents field from ''pData'' for ''aFile''. * The [[#poll(inout_pollData)|poll]] function uses the checkedEvents * as input. The following checkedEvents can be returned: * * POLLNOTHING no data can be read or written. * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read and written (POLLIN and POLLOUT). * @return POLLNOTHING, POLLIN, POLLOUT or POLLINOUT, depending on * the events added and removed for ''aFile' with * ''addCheck'' and ''removeCheck''. *) const func integer: getCheck (inout pollData: pData, in file: aFile) is DYNAMIC; (** * Waits for one or more of the checkedEvents from ''pData''. * ''Poll'' waits until one of the checkedEvents for a * corresponding socket occurs. If a checkedEvents occurs * the eventFindings field is assigned a value. The following * eventFindings values are assigned: * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read and written (POLLIN and POLLOUT). * @exception FILE_ERROR The system function returns an error. *) const proc: poll (inout pollData: pData) is action "POL_POLL"; (** * Return the eventFindings field from ''pData'' for ''aSocket''. * The [[#poll(inout_pollData)|poll]] function assigns the * eventFindings for ''aSocket'' to ''pData''. The following * eventFindings can be returned: * * POLLNOTHING no data can be read or written. * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read and written (POLLIN and POLLOUT). * @return POLLNOTHING, POLLIN, POLLOUT or POLLINOUT, depending on * the findings of [[#poll(inout_pollData)|poll]] * concerning ''aSocket''. *) const func integer: getFinding (inout pollData: pData, in PRIMITIVE_SOCKET: aSocket) is action "POL_GET_FINDING"; const func integer: getFinding (inout pollData: pData, in socket: aSocket) is return getFinding(pData, aSocket.sock); (** * Return the eventFindings field from ''pData'' for ''aFile''. * The [[#poll(inout_pollData)|poll]] function assigns the * eventFindings for ''aFile'' to ''pData''. The following * eventFindings can be returned: * * POLLNOTHING no data can be read or written. * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read and written (POLLIN and POLLOUT). * @return POLLNOTHING, POLLIN, POLLOUT or POLLINOUT, depending on * the findings of [[#poll(inout_pollData)|poll]] * concerning ''aFile''. *) const func integer: getFinding (inout pollData: pData, in file: aFile) is DYNAMIC; (** * Reset the ''pollData'' iterator to process checkedEvents. * The following calls of ''hasNext'' and ''nextFile'' refer to * the checkedEvents of the given ''pollMode''. ''PollMode'' * can have one of the following values: * * POLLNOTHING don't iterate (''hasNext'' returns FALSE). * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read or written (POLLIN and POLLOUT). * @exception RANGE_ERROR Illegal value for ''pollMode''. *) const proc: iterChecks (in pollData: pData, in integer: pollMode) is action "POL_ITER_CHECKS"; (** * Reset the ''pollData'' iterator to process eventFindings. * The following calls of ''hasNext'' and ''nextFile'' refer to * the eventFindings of the given ''pollMode''. ''PollMode'' * can have one of the following values: * * POLLNOTHING don't iterate (''hasNext'' returns FALSE). * * POLLIN data can be read from the corresponding [[socket]]. * * POLLOUT data can be written to the corresponding socket. * * POLLINOUT data can be read or written (POLLIN and POLLOUT). * @exception RANGE_ERROR Illegal value for ''pollMode''. *) const proc: iterFindings (in pollData: pData, in integer: pollMode) is action "POL_ITER_FINDINGS"; (** * Determine if the ''pData'' iterator can deliver another [[file]]. * @return TRUE if ''nextFile'' would return another file from the * ''pData'' iterator, FALSE otherwise. *) const func boolean: hasNext (inout pollData: pData) is action "POL_HAS_NEXT"; const func file: nextFile (inout pollData: pData, in file: nullFile) is action "POL_NEXT_FILE"; (** * Get the next [[file]] from the ''pData'' iterator. * Successive calls of ''nextFile'' return all files from the ''pData'' * iterator. The file returned by ''nextFile'' is determined with the * function ''addCheck''. The files covered by the ''pData'' iterator * are determined with ''iterChecks'' or ''iterFindings''. * @return the next file from the ''pData'' iterator, or STD_NULL, * if no file from the ''pData'' iterator is available. *) const func file: nextFile (inout pollData: pData) is return nextFile(pData, STD_NULL); (** * For-loop to loop over the values of the ''pData'' iterator. * The for-loop loops over the values determined by the ''pollMode''. * With ''iterCheck'' or ''iterFindings'' the ''pollMode'' of the * iterator is determined. *) const proc: for (inout file: forVar) range (inout pollData: pData) do (in proc: statements) end for is func begin while hasNext(pData) do forVar := nextFile(pData); statements; end while; end func;