Changeset 92a3586 in rtems


Ignore:
Timestamp:
Apr 3, 2012, 1:14:50 PM (8 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Children:
63defa58
Parents:
350127a2
git-author:
Sebastian Huber <sebastian.huber@…> (04/03/12 13:14:50)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/03/12 15:17:34)
Message:

Filesystem: IO control based select() support

This is a hack. The Termios write facility has a severe issue with the
lacking support of non-blocking writes.

Location:
cpukit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/include/sys/ioccom.h

    r350127a2 r92a3586  
    3737#define _SYS_IOCCOM_H_
    3838
    39 #include <sys/types.h>
     39#include <rtems.h>
    4040
    4141/*
     
    7777#define       RTEMS_IO_SNDWAKEUP      5
    7878
     79typedef enum {
     80  RTEMS_IOCTL_SELECT_OTHER,
     81  RTEMS_IOCTL_SELECT_READ,
     82  RTEMS_IOCTL_SELECT_WRITE
     83} rtems_ioctl_select_kind;
     84
     85/**
     86 * @brief IO control request for select() support.
     87 *
     88 * The driver shall return
     89 *   - 1, when the request can be fullfilled immediately,
     90 *   - 0, when the request task must wait, and
     91 *   - -1, in case of an error.
     92 */
     93typedef struct {
     94  rtems_ioctl_select_kind kind;
     95  rtems_id request_task_id;
     96} rtems_ioctl_select_request;
     97
     98#define RTEMS_IOCTL_SELECT _IOW('R', 0, rtems_ioctl_select_request)
     99
     100#define RTEMS_IOCTL_SELECT_EVENT RTEMS_EVENT_24
     101
    79102/* copied from libnetworking/sys/filio.h and commented out there */
    80103/* Generic file-descriptor ioctl's. */
  • cpukit/libcsupport/src/termios.c

    r350127a2 r92a3586  
    510510}
    511511
     512static bool
     513rtems_termios_can_read (const struct rtems_termios_tty *tty)
     514{
     515  if (tty->cindex == tty->ccount) {
     516    if (tty->device.outputUsesInterrupts == TERMIOS_IRQ_DRIVEN) {
     517      return tty->rawInBuf.Head != tty->rawInBuf.Tail;
     518    } else {
     519      return true;
     520    }
     521  } else {
     522    return tty->cindex < tty->ccount;
     523  }
     524}
     525
     526static bool
     527rtems_termios_can_write (const struct rtems_termios_tty *tty)
     528{
     529  /*
     530   * Termios has no non-blocking writes.  In case the raw output buffer is
     531   * full, we wait for the interrupt or poll.
     532   */
     533  return true;
     534}
     535
     536static void
     537rtems_termios_select_wakeup (struct termios *tty, void *arg)
     538{
     539  rtems_id task_id = (rtems_id) arg;
     540  rtems_status_code sc = rtems_event_send (task_id, RTEMS_IOCTL_SELECT_EVENT);
     541  if (sc != RTEMS_SUCCESSFUL)
     542    rtems_fatal_error_occurred (sc);
     543}
     544
     545static int
     546rtems_termios_select (struct rtems_termios_tty *tty,
     547                      const rtems_ioctl_select_request *request)
     548{
     549  int rv = 0;
     550
     551  rtems_interrupt_level level;
     552  rtems_interrupt_disable(level);
     553  switch (request->kind) {
     554    case RTEMS_IOCTL_SELECT_READ:
     555      if (rtems_termios_can_read (tty)) {
     556        rv = 1;
     557      } else {
     558        tty->tty_rcvwakeup = 0;
     559        tty->tty_rcv.sw_pfn = rtems_termios_select_wakeup;
     560        tty->tty_rcv.sw_arg = (void *) request->request_task_id;
     561      }
     562      break;
     563    case RTEMS_IOCTL_SELECT_WRITE:
     564      if (rtems_termios_can_write (tty)) {
     565        rv = 1;
     566      } else {
     567        tty->tty_snd.sw_pfn = rtems_termios_select_wakeup;
     568        tty->tty_snd.sw_arg = (void *) request->request_task_id;
     569      }
     570      break;
     571    default:
     572      break;
     573  }
     574  rtems_interrupt_enable(level);
     575
     576  return rv;
     577}
     578
    512579rtems_status_code
    513580rtems_termios_ioctl (void *arg)
     
    531598      sc = RTEMS_INVALID_NUMBER;
    532599    }
     600    break;
     601
     602  case RTEMS_IOCTL_SELECT:
     603    args->ioctl_return = rtems_termios_select (tty, args->buffer);
    533604    break;
    534605
  • cpukit/libnetworking/rtems/rtems_select.c

    r350127a2 r92a3586  
    3030#include <net/if.h>
    3131#include <net/route.h>
     32
     33RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_OTHER == 0, other);
     34RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_READ == FREAD, fread);
     35RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_WRITE == FWRITE, fwrite);
     36RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_EVENT == SBWAIT_EVENT, sbwait_event);
    3237
    3338/*
     
    8994        int n = 0;
    9095        static int flag[3] = { FREAD, FWRITE, 0 };
     96        int update_obits;
     97        int rv;
     98        rtems_ioctl_select_request select_request;
     99
     100        select_request.request_task_id = tid;
    91101
    92102        for (msk = 0; msk < 3; msk++) {
     
    99109                                        continue;
    100110                                bits &= ~bit;
     111                                update_obits = 0;
    101112                                so = rtems_bsdnet_fdToSocket (fd);
    102                                 if (so == NULL)
    103                                         return (EBADF);
    104                                 if (socket_select (so, flag[msk], tid)) {
     113                                if (so != NULL) {
     114                                        if (socket_select (so, flag[msk], tid)) {
     115                                                update_obits = 1;
     116                                        }
     117                                } else {
     118                                        select_request.kind = flag[msk];
     119
     120                                        rtems_bsdnet_semaphore_release();
     121                                        rv = ioctl (fd, RTEMS_IOCTL_SELECT, &select_request);
     122                                        rtems_bsdnet_semaphore_obtain();
     123                                        if (rv == 1) {
     124                                                update_obits = 1;
     125                                        } else if (rv != 0) {
     126                                                return (EBADF);
     127                                        }
     128                                }
     129
     130                                if (update_obits) {
    105131                                        obits[msk][fd/NFDBITS] |=
    106132                                                        (1 << (fd % NFDBITS));
Note: See TracChangeset for help on using the changeset viewer.