esp8266-std/ESP8266_RTOS_SDK/third_party/nopoll/nopoll_io.c

234 lines
6.3 KiB
C
Raw Normal View History

2018-11-23 01:43:17 +00:00
/*
* LibNoPoll: A websocket library
* Copyright (C) 2013 Advanced Software Production Line, S.L.
*
* This program 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.
*
* This program 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., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*
* You may find a copy of the license under this software is released
* at COPYING file. This is LGPL software: you are welcome to develop
* proprietary applications using this library without any royalty or
* fee but returning back any change, improvement or addition in the
* form of source code, project image, documentation patches, etc.
*
* For commercial support on build Websocket enabled solutions
* contact us:
*
* Postal address:
* Advanced Software Production Line, S.L.
* Edificio Alius A, Oficina 102,
* C/ Antonio Suarez 10,
* Alcalá de Henares 28802 Madrid
* Spain
*
* Email address:
* info@aspl.es - http://www.aspl.es/nopoll
*/
#include <nopoll_io.h>
#include <nopoll_private.h>
typedef struct _noPollSelect {
noPollCtx * ctx;
fd_set set;
int length;
int max_fds;
} noPollSelect;
/**
* @internal nopoll implementation to create a compatible "select" IO
* call fd set reference.
*
* @return A newly allocated fd_set reference.
*/
noPollPtr nopoll_io_wait_select_create (noPollCtx * ctx)
{
noPollSelect * select = nopoll_new (noPollSelect, 1);
/* set default behaviour expected for the set */
select->ctx = ctx;
/* clear the set */
FD_ZERO (&(select->set));
return select;
}
/**
* @internal noPoll implementation to destroy the "select" IO call
* created by the default create.
*
* @param fd_group The fd group to be deallocated.
*/
void nopoll_io_wait_select_destroy (noPollCtx * ctx, noPollPtr fd_group)
{
fd_set * __fd_set = (fd_set *) fd_group;
/* release memory allocated */
nopoll_free (__fd_set);
/* nothing more to do */
return;
}
/**
* @internal noPoll implementation to clear the "select" IO call
* created by the default create.
*
* @param fd_group The fd group to be deallocated.
*/
void nopoll_io_wait_select_clear (noPollCtx * ctx, noPollPtr __fd_group)
{
noPollSelect * select = (noPollSelect *) __fd_group;
/* clear the fd set */
select->length = 0;
FD_ZERO (&(select->set));
/* nothing more to do */
return;
}
/**
* @internal Default internal implementation for the wait operation to
* change its status at least one socket description inside the fd set
* provided.
*
* @param __fd_group The fd set having all sockets to be watched.
* @param wait_to The operation requested.
*
* @return Number of connections that changed or -1 if something wailed
*/
int nopoll_io_wait_select_wait (noPollCtx * ctx, noPollPtr __fd_group)
{
int result = -1;
struct timeval tv;
noPollSelect * _select = (noPollSelect *) __fd_group;
/* init wait */
tv.tv_sec = 0;
tv.tv_usec = 500000;
result = select (_select->max_fds + 1, &(_select->set), NULL, NULL, &tv);
/* check result */
if ((result == NOPOLL_SOCKET_ERROR) && (errno == NOPOLL_EINTR))
return -1;
return result;
}
/**
* @internal noPoll select implementation for the "add to" on fd set
* operation.
*
* @param fds The socket descriptor to be added.
*
* @param fd_set The fd set where the socket descriptor will be added.
*/
nopoll_bool nopoll_io_wait_select_add_to (int fds,
noPollCtx * ctx,
noPollConn * conn,
noPollPtr __fd_set)
{
noPollSelect * select = (noPollSelect *) __fd_set;
if (fds < 0) {
nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL,
"received a non valid socket (%d), unable to add to the set", fds);
return nopoll_false;
}
/* set the value */
FD_SET (fds, &(select->set));
/* update length */
select->length++;
/* update max fds */
if (fds > select->max_fds)
select->max_fds = fds;
return nopoll_true;
}
/**
* @internal
*
* @brief Default noPoll implementation for the "is set" on fd
* set operation.
*
* @param fds The socket descriptor to be checked to be active on the
* given fd group.
*
* @param fd_set The fd set where the socket descriptor will be checked.
*/
nopoll_bool nopoll_io_wait_select_is_set (noPollCtx * ctx,
int fds,
noPollPtr __fd_set)
{
noPollSelect * select = (noPollSelect *) __fd_set;
return FD_ISSET (fds, &(select->set));
}
/**
* @brief Creates an object that represents the best IO wait mechanism
* found on the current system.
*
* @param ctx The context where the engine will be created/associated.
*
* @param engine Use \ref NOPOLL_IO_ENGINE_DEFAULT or the engine you
* want to use.
*
* @return The selected IO wait mechanism or NULL if it fails.
*/
noPollIoEngine * nopoll_io_get_engine (noPollCtx * ctx, noPollIoEngineType engine_type)
{
noPollIoEngine * engine = nopoll_new (noPollIoEngine, 1);
if (engine == NULL)
return NULL;
/* configure default implementation */
engine->create = nopoll_io_wait_select_create;
engine->destroy = nopoll_io_wait_select_destroy;
engine->clear = nopoll_io_wait_select_clear;
engine->wait = nopoll_io_wait_select_wait;
engine->addto = nopoll_io_wait_select_add_to;
engine->isset = nopoll_io_wait_select_is_set;
/* call to create the object */
engine->ctx = ctx;
engine->io_object = engine->create (ctx);
/* return the engine that was created */
return engine;
}
/**
* @brief Release the io engine created by \ref nopoll_io_get_engine.
*
* @param engine The engine to be released.
*/
void nopoll_io_release_engine (noPollIoEngine * engine)
{
if (engine == NULL)
return;
engine->destroy (engine->ctx, engine->io_object);
nopoll_free (engine);
return;
}