Exemple #1
0
int_t select(int_t nfds, fd_set *readfds, fd_set *writefds,
   fd_set *exceptfds, const timeval *timeout)
{
   int_t i;
   int_t j;
   int_t n;
   int_t s;
   time_t time;
   uint_t eventMask;
   uint_t eventFlags;
   OsEvent *event;
   fd_set *fds;

   //Create an event object to get notified of socket events
   event = osEventCreate(FALSE, FALSE);

   //Any error to report?
   if(event == OS_INVALID_HANDLE)
   {
      socketError(NULL, ERROR_OUT_OF_RESOURCES);
      return SOCKET_ERROR;
   }

   //Parse all the descriptor sets
   for(i = 0; i < 3; i ++)
   {
      //Select the suitable descriptor set
      switch(i)
      {
      case 0:
         //Set of sockets to be checked for readability
         fds = readfds;
         eventMask = SOCKET_EVENT_RX_READY;
         break;
      case 1:
         //Set of sockets to be checked for writability
         fds = writefds;
         eventMask = SOCKET_EVENT_TX_READY;
         break;
      default:
         //Set of sockets to be checked for errors
         fds = exceptfds;
         eventMask = SOCKET_EVENT_CLOSED;
         break;
      }

      //Each descriptor is optional and may be omitted
      if(fds != NULL)
      {
         //Parse the current set of sockets
         for(j = 0; j < fds->fd_count; j++)
         {
            //Get the descriptor associated with the current entry
            s = fds->fd_array[j];
            //Subscribe to the requested events
            socketRegisterEvents(&socketTable[s], event, eventMask);
         }
      }
   }

   //Retrieve timeout value
   if(timeout != NULL)
      time = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
   else
      time = INFINITE_DELAY;

   //Block the current task until an event occurs
   osEventWait(event, time);

   //Count the number of events in the signaled state
   n = 0;

   //Parse all the descriptor sets
   for(i = 0; i < 3; i ++)
   {
      //Select the suitable descriptor set
      switch(i)
      {
      case 0:
         //Set of sockets to be checked for readability
         fds = readfds;
         eventMask = SOCKET_EVENT_RX_READY;
         break;
      case 1:
         //Set of sockets to be checked for writability
         fds = writefds;
         eventMask = SOCKET_EVENT_TX_READY;
         break;
      default:
         //Set of sockets to be checked for errors
         fds = exceptfds;
         eventMask = SOCKET_EVENT_CLOSED;
         break;
      }

      //Each descriptor is optional and may be omitted
      if(fds != NULL)
      {
         //Parse the current set of sockets
         for(j = 0; j < fds->fd_count; )
         {
            //Get the descriptor associated with the current entry
            s = fds->fd_array[j];
            //Retrieve event flags for the current socket
            socketGetEvents(&socketTable[s], &eventFlags);
            //Unsubscribe previously registered events
            socketUnregisterEvents(&socketTable[s]);

            //Event flag is set?
            if(eventFlags & eventMask)
            {
               //Track the number of events in the signaled state
               n++;
               //Jump to the next socket descriptor
               j++;
            }
            else
            {
               //Remove descriptor from the current set
               selectFdClr(fds, s);
            }
         }
      }
   }

   //Close event
   osEventClose(event);
   //Return the number of events in the signaled state
   return n;
}
Exemple #2
0
error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent, systime_t timeout)
{
   uint_t i;
   bool_t status;
   OsEvent *event;
   OsEvent eventObject;

   //Check parameters
   if(!eventDesc || !size)
      return ERROR_INVALID_PARAMETER;

   //Try to use the supplied event object to receive notifications
   if(!extEvent)
   {
      //Create an event object only if necessary
      if(!osCreateEvent(&eventObject))
      {
         //Report an error
         return ERROR_OUT_OF_RESOURCES;
      }

      //Reference to the newly created event
      event = &eventObject;
   }
   else
   {
      //Reference to the external event
      event = extEvent;
   }

   //Loop through descriptors
   for(i = 0; i < size; i++)
   {
      //Clear event flags
      eventDesc[i].eventFlags = 0;
      //Subscribe to the requested events
      socketRegisterEvents(eventDesc[i].socket, event, eventDesc[i].eventMask);
   }

   //Block the current task until an event occurs
   status = osWaitForEvent(event, timeout);

   //Any socket event is in the signaled state?
   if(status)
   {
      //Loop through descriptors
      for(i = 0; i < size; i++)
      {
         //Retrieve event flags for the current socket
         socketGetEvents(eventDesc[i].socket, &eventDesc[i].eventFlags);
         //Clear unnecessary flags
         eventDesc[i].eventFlags &= eventDesc[i].eventMask;
      }
   }

   //Unsubscribe previously registered events
   for(i = 0; i < size; i++)
      socketUnregisterEvents(eventDesc[i].socket);

   //Reset event object before exiting...
   osResetEvent(event);

   //Release previously allocated resources
   if(!extEvent)
      osDeleteEvent(&eventObject);

   //Return status code
   return status ? NO_ERROR : ERROR_TIMEOUT;
}