Ejemplo n.º 1
0
static int
wait_on_socket (int sock)
{
  struct pollfd fds[1];
  fds[0].fd = sock;
  fds[0].events = POLLIN | POLLERR | POLLHUP;
  int n = __poll (fds, 1, 5 * 1000);
  if (n == -1 && __builtin_expect (errno == EINTR, 0))
    {
      /* Handle the case where the poll() call is interrupted by a
	 signal.  We cannot just use TEMP_FAILURE_RETRY since it might
	 lead to infinite loops.  */
      struct timeval now;
      (void) __gettimeofday (&now, NULL);
      long int end = (now.tv_sec + 5) * 1000 + (now.tv_usec + 500) / 1000;
      while (1)
	{
	  long int timeout = end - (now.tv_sec * 1000
				    + (now.tv_usec + 500) / 1000);
	  n = __poll (fds, 1, timeout);
	  if (n != -1 || errno != EINTR)
	    break;
	  (void) __gettimeofday (&now, NULL);
	}
    }

  return n;
}
Ejemplo n.º 2
0
static int
open_socket (void)
{
  int sock = __socket (PF_UNIX, SOCK_STREAM, 0);
  if (sock < 0)
    return -1;

  /* Make socket non-blocking.  */
  int fl = __fcntl (sock, F_GETFL);
  if (fl != -1)
    __fcntl (sock, F_SETFL, fl | O_NONBLOCK);

  struct sockaddr_un sun;
  sun.sun_family = AF_UNIX;
  strcpy (sun.sun_path, _PATH_NSCDSOCKET);
  if (__connect (sock, (struct sockaddr *) &sun, sizeof (sun)) < 0
      && errno != EINPROGRESS)
    goto out;

  struct pollfd fds[1];
  fds[0].fd = sock;
  fds[0].events = POLLOUT | POLLERR | POLLHUP;
  if (__poll (fds, 1, 5 * 1000) > 0)
    /* Success.  We do not check for success of the connect call here.
       If it failed, the following operations will fail.  */
    return sock;

 out:
  close_not_cancel_no_status (sock);

  return -1;
}
Ejemplo n.º 3
0
static void __end()
{
  int ii, ievt, rem_count;
  int len, type, lock_key;
  DMANODE *outEvent;
  int oldnumber;
  int iwait=0;
  int blocksLeft=0;

  /* Disable Triggers */
#ifdef TID_MASTER
  tidDisableTriggerSource(1);
#endif

  /* Before disconnecting... wait for blocks to be emptied */
  blocksLeft=tidBReady();
  if(blocksLeft)
    {
      printf("... end:  Blocks left on the TID (%d)\n",blocksLeft);
      while(iwait < 100)
	{
	  if(blocksLeft<=0)
	    break;
	  blocksLeft=tidBReady();
	  iwait++;
	}
      printf("... end:  Blocks left on the TID (%d)\n",blocksLeft);
    }
  tidStatus();
  tidIntDisable();
  tidIntDisconnect();

  /* Execute User defined end */
  rocEnd();

  CDODISABLE(TIDPRIMARY,1,0);
 
  /* we need to make sure all events taken by the
     VME are collected from the vmeOUT queue */

  rem_count = getOutQueueCount();
  if (rem_count > 0) 
    {
      printf("tidprimary_list End: %d events left on vmeOUT queue (will now de-queue them)\n",rem_count);
      /* This wont work without a secondary readout list (will crash EB or hang the ROC) */
      for(ii=0;ii<rem_count;ii++) 
	{
	  __poll();
	}
    }
  else
    {
      printf("tidprimary_list End: vmeOUT queue Empty\n");
    }
      
  daLogMsg("INFO","End Executed");

  if (__the_event__) WRITE_EVENT_;
} /* end end block */
Ejemplo n.º 4
0
void
svc_run (void)
{
  int i;
  struct pollfd *my_pollfd = NULL;
  int last_max_pollfd = 0;

  for (;;)
    {
      int max_pollfd = svc_max_pollfd;
      if (max_pollfd == 0 && svc_pollfd == NULL)
	break;

      if (last_max_pollfd != max_pollfd)
	{
	  struct pollfd *new_pollfd
	    = realloc (my_pollfd, sizeof (struct pollfd) * max_pollfd);

	  if (new_pollfd == NULL)
	    {
	      perror (_("svc_run: - out of memory"));
	      break;
	    }

	  my_pollfd = new_pollfd;
	  last_max_pollfd = max_pollfd;
	}

      for (i = 0; i < max_pollfd; ++i)
	{
	  my_pollfd[i].fd = svc_pollfd[i].fd;
	  my_pollfd[i].events = svc_pollfd[i].events;
	  my_pollfd[i].revents = 0;
	}

      switch (i = __poll (my_pollfd, max_pollfd, -1))
	{
	case -1:
	  if (errno == EINTR)
	    continue;
	  perror (_("svc_run: - poll failed"));
	  break;
	case 0:
	  continue;
	default:
	  INTUSE(svc_getreq_poll) (my_pollfd, i);
	  continue;
	}
      break;
    }

  free (my_pollfd);
}
Ejemplo n.º 5
0
/*
 * Interface between xdr serializer and tcp connection.
 * Behaves like the system calls, read & write, but keeps some error state
 * around for the rpc level.
 */
static int
readtcp (char *ctptr, char *buf, int len)
{
  struct ct_data *ct = (struct ct_data *)ctptr;
  struct pollfd fd;
  int milliseconds = (ct->ct_wait.tv_sec * 1000) +
    (ct->ct_wait.tv_usec / 1000);

  if (len == 0)
    return 0;

  fd.fd = ct->ct_sock;
  fd.events = POLLIN;
  while (TRUE)
    {
      switch (__poll(&fd, 1, milliseconds))
	{
	case 0:
	  ct->ct_error.re_status = RPC_TIMEDOUT;
	  return -1;

	case -1:
	  if (errno == EINTR)
	    continue;
	  ct->ct_error.re_status = RPC_CANTRECV;
	  ct->ct_error.re_errno = errno;
	  return -1;
	}
      break;
    }
  switch (len = __read (ct->ct_sock, buf, len))
    {

    case 0:
      /* premature eof */
      ct->ct_error.re_errno = ECONNRESET;
      ct->ct_error.re_status = RPC_CANTRECV;
      len = -1;			/* it's really an error */
      break;

    case -1:
      ct->ct_error.re_errno = errno;
      ct->ct_error.re_status = RPC_CANTRECV;
      break;
    }
  return len;
}
Ejemplo n.º 6
0
int
ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
       const sigset_t *sigmask)
{
  int tval = -1;

  /* poll uses a simple millisecond value.  Convert it.  */
  if (timeout != NULL)
    {
      if (timeout->tv_sec < 0
	  || timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)
	{
	  __set_errno (EINVAL);
	  return -1;
	}

      if (timeout->tv_sec > INT_MAX / 1000
	  || (timeout->tv_sec == INT_MAX / 1000
	      && ((timeout->tv_nsec + 999999) / 1000000 > INT_MAX % 1000)))
	/* We cannot represent the timeout in an int value.  Wait
	   forever.  */
	tval = -1;
      else
	tval = (timeout->tv_sec * 1000
		+ (timeout->tv_nsec + 999999) / 1000000);
    }

  /* The setting and restoring of the signal mask and the select call
     should be an atomic operation.  This can't be done without kernel
     help.  */
  sigset_t savemask;
  if (sigmask != NULL)
    __sigprocmask (SIG_SETMASK, sigmask, &savemask);

  /* Note the ppoll() is a cancellation point.  But since we call
     poll() which itself is a cancellation point we do not have
     to do anything here.  */
  int retval = __poll (fds, nfds, tval);

  if (sigmask != NULL)
    __sigprocmask (SIG_SETMASK, &savemask, NULL);

  return retval;
}
/*
 * reads data from the tcp connection.
 * any error is fatal and the connection is closed.
 * (And a read of zero bytes is a half closed stream => error.)
 */
static int
readtcp (char *xprtptr, char *buf, int len)
{
  SVCXPRT *xprt = (SVCXPRT *)xprtptr;
  int sock = xprt->xp_sock;
  int milliseconds = 35 * 1000;
  struct pollfd pollfd;

  do
    {
      pollfd.fd = sock;
      pollfd.events = POLLIN;
      switch (__poll (&pollfd, 1, milliseconds))
	{
	case -1:
	  if (errno == EINTR)
	    continue;
	  /*FALLTHROUGH*/
	case 0:
	  goto fatal_err;
	default:
          if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
              || (pollfd.revents & POLLNVAL))
            goto fatal_err;
	  break;
	}
    }
  while ((pollfd.revents & POLLIN) == 0);

  if ((len = __read (sock, buf, len)) > 0)
    return len;

 fatal_err:
  ((struct tcp_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
  return -1;
}
Ejemplo n.º 8
0
__pthread_manager(void *arg)
{
  pthread_descr self = manager_thread = arg;
  int reqfd = __pthread_manager_reader;
  struct pollfd ufd;
  sigset_t manager_mask;
  int n;
  struct pthread_request request;

  /* If we have special thread_self processing, initialize it.  */
#ifdef INIT_THREAD_SELF
  INIT_THREAD_SELF(self, 1);
#endif
#if !(USE_TLS && HAVE___THREAD)
  /* Set the error variable.  */
  self->p_errnop = &self->p_errno;
  self->p_h_errnop = &self->p_h_errno;
#endif
  /* Block all signals except __pthread_sig_cancel and SIGTRAP */
  sigfillset(&manager_mask);
  sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */
  sigdelset(&manager_mask, SIGTRAP);            /* for debugging purposes */
  if (__pthread_threads_debug && __pthread_sig_debug > 0)
    sigdelset(&manager_mask, __pthread_sig_debug);
  sigprocmask(SIG_SETMASK, &manager_mask, NULL);
  /* Raise our priority to match that of main thread */
  __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
  /* Synchronize debugging of the thread manager */
  n = TEMP_FAILURE_RETRY(read_not_cancel(reqfd, (char *)&request,
					 sizeof(request)));
  ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
  ufd.fd = reqfd;
  ufd.events = POLLIN;
  /* Enter server loop */
  while(1) {
    n = __poll(&ufd, 1, 2000);

    /* Check for termination of the main thread */
    if (getppid() == 1) {
      pthread_kill_all_threads(SIGKILL, 0);
      _exit(0);
    }
    /* Check for dead children */
    if (terminated_children) {
      terminated_children = 0;
      pthread_reap_children();
    }
    /* Read and execute request */
    if (n == 1 && (ufd.revents & POLLIN)) {
      n = TEMP_FAILURE_RETRY(read_not_cancel(reqfd, (char *)&request,
					     sizeof(request)));
#ifdef DEBUG
      if (n < 0) {
	char d[64];
	write(STDERR_FILENO, d, snprintf(d, sizeof(d), "*** read err %m\n"));
      } else if (n != sizeof(request)) {
	write(STDERR_FILENO, "*** short read in manager\n", 26);
      }
#endif

      switch(request.req_kind) {
      case REQ_CREATE:
        request.req_thread->p_retcode =
          pthread_handle_create((pthread_t *) &request.req_thread->p_retval,
                                request.req_args.create.attr,
                                request.req_args.create.fn,
                                request.req_args.create.arg,
                                &request.req_args.create.mask,
                                request.req_thread->p_pid,
				request.req_thread->p_report_events,
				&request.req_thread->p_eventbuf.eventmask);
        restart(request.req_thread);
        break;
      case REQ_FREE:
	pthread_handle_free(request.req_args.free.thread_id);
        break;
      case REQ_PROCESS_EXIT:
        pthread_handle_exit(request.req_thread,
                            request.req_args.exit.code);
	/* NOTREACHED */
        break;
      case REQ_MAIN_THREAD_EXIT:
        main_thread_exiting = 1;
	/* Reap children in case all other threads died and the signal handler
	   went off before we set main_thread_exiting to 1, and therefore did
	   not do REQ_KICK. */
	pthread_reap_children();

        if (__pthread_main_thread->p_nextlive == __pthread_main_thread) {
          restart(__pthread_main_thread);
	  /* The main thread will now call exit() which will trigger an
	     __on_exit handler, which in turn will send REQ_PROCESS_EXIT
	     to the thread manager. In case you are wondering how the
	     manager terminates from its loop here. */
	}
        break;
      case REQ_POST:
        sem_post(request.req_args.post);
        break;
      case REQ_DEBUG:
	/* Make gdb aware of new thread and gdb will restart the
	   new thread when it is ready to handle the new thread. */
	if (__pthread_threads_debug && __pthread_sig_debug > 0)
	  raise(__pthread_sig_debug);
        break;
      case REQ_KICK:
	/* This is just a prod to get the manager to reap some
	   threads right away, avoiding a potential delay at shutdown. */
	break;
      case REQ_FOR_EACH_THREAD:
	pthread_for_each_thread(request.req_args.for_each.arg,
	                        request.req_args.for_each.fn);
	restart(request.req_thread);
	break;
      }
    }
  }
}
Ejemplo n.º 9
0
int
rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep,
       struct rpc_timeval *timeout)
{
  int s;
  struct pollfd fd;
  int milliseconds;
  int res;
  /* RFC 868 says the time is transmitted as a 32-bit value.  */
  uint32_t thetime;
  struct sockaddr_in from;
  int fromlen;
  int type;

  if (timeout == NULL)
    type = SOCK_STREAM;
  else
    type = SOCK_DGRAM;

  s = __socket (AF_INET, type, 0);
  if (s < 0)
    return (-1);

  addrp->sin_family = AF_INET;
  addrp->sin_port = htons (IPPORT_TIMESERVER);
  if (type == SOCK_DGRAM)
    {
      res = __sendto (s, (char *) &thetime, sizeof (thetime), 0,
		      (struct sockaddr *) addrp, sizeof (*addrp));
      if (res < 0)
	{
	  do_close (s);
	  return -1;
	}
      milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
      fd.fd = s;
      fd.events = POLLIN;
      do
	res = __poll (&fd, 1, milliseconds);
      while (res < 0 && errno == EINTR);
      if (res <= 0)
	{
	  if (res == 0)
	    __set_errno (ETIMEDOUT);
	  do_close (s);
	  return (-1);
	}
      fromlen = sizeof (from);
      res = __recvfrom (s, (char *) &thetime, sizeof (thetime), 0,
			(struct sockaddr *) &from, &fromlen);
      do_close (s);
      if (res < 0)
	return -1;
    }
  else
    {
      if (__connect (s, (struct sockaddr *) addrp, sizeof (*addrp)) < 0)
	{
	  do_close (s);
	  return -1;
	}
      res = __read (s, (char *) &thetime, sizeof (thetime));
      do_close (s);
      if (res < 0)
	return (-1);
    }
  if (res != sizeof (thetime))
    {
      __set_errno (EIO);
      return -1;
    }
  thetime = ntohl (thetime);
  timep->tv_sec = thetime - TOFFSET;
  timep->tv_usec = 0;
  return 0;
}
Ejemplo n.º 10
0
static enum clnt_stat
clntudp_call (/* client handle */
	      CLIENT *cl,
	      /* procedure number */
	      u_long proc,
	      /* xdr routine for args */
	      xdrproc_t xargs,
	      /* pointer to args */
	      caddr_t argsp,
	      /* xdr routine for results */
	      xdrproc_t xresults,
	      /* pointer to results */
	      caddr_t resultsp,
	      /* seconds to wait before giving up */
	      struct timeval utimeout)
{
  struct cu_data *cu = (struct cu_data *) cl->cl_private;
  XDR *xdrs;
  int outlen = 0;
  int inlen;
  socklen_t fromlen;
  struct pollfd fd;
  int milliseconds = (cu->cu_wait.tv_sec * 1000) +
    (cu->cu_wait.tv_usec / 1000);
  struct sockaddr_in from;
  struct rpc_msg reply_msg;
  XDR reply_xdrs;
  struct timeval time_waited;
  bool_t ok;
  int nrefreshes = 2;		/* number of times to refresh cred */
  struct timeval timeout;
  int anyup;			/* any network interface up */

  if (cu->cu_total.tv_usec == -1)
    {
      timeout = utimeout;	/* use supplied timeout */
    }
  else
    {
      timeout = cu->cu_total;	/* use default timeout */
    }

  time_waited.tv_sec = 0;
  time_waited.tv_usec = 0;
call_again:
  xdrs = &(cu->cu_outxdrs);
  if (xargs == NULL)
    goto get_reply;
  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS (xdrs, cu->cu_xdrpos);
  /*
   * the transaction is the first thing in the out buffer
   */
  (*(uint32_t *) (cu->cu_outbuf))++;
  if ((!XDR_PUTLONG (xdrs, (long *) &proc)) ||
      (!AUTH_MARSHALL (cl->cl_auth, xdrs)) ||
      (!(*xargs) (xdrs, argsp)))
    return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
  outlen = (int) XDR_GETPOS (xdrs);

send_again:
  if (__sendto (cu->cu_sock, cu->cu_outbuf, outlen, 0,
		(struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
      != outlen)
    {
      cu->cu_error.re_errno = errno;
      return (cu->cu_error.re_status = RPC_CANTSEND);
    }

  /*
   * Hack to provide rpc-based message passing
   */
  if (timeout.tv_sec == 0 && timeout.tv_usec == 0)
    {
      return (cu->cu_error.re_status = RPC_TIMEDOUT);
    }
 get_reply:
  /*
   * sub-optimal code appears here because we have
   * some clock time to spare while the packets are in flight.
   * (We assume that this is actually only executed once.)
   */
  reply_msg.acpted_rply.ar_verf = _null_auth;
  reply_msg.acpted_rply.ar_results.where = resultsp;
  reply_msg.acpted_rply.ar_results.proc = xresults;
  fd.fd = cu->cu_sock;
  fd.events = POLLIN;
  anyup = 0;
  for (;;)
    {
      switch (__poll (&fd, 1, milliseconds))
	{

	case 0:
	  if (anyup == 0)
	    {
	      anyup = is_network_up (cu->cu_sock);
	      if (!anyup)
		return (cu->cu_error.re_status = RPC_CANTRECV);
	    }

	  time_waited.tv_sec += cu->cu_wait.tv_sec;
	  time_waited.tv_usec += cu->cu_wait.tv_usec;
	  while (time_waited.tv_usec >= 1000000)
	    {
	      time_waited.tv_sec++;
	      time_waited.tv_usec -= 1000000;
	    }
	  if ((time_waited.tv_sec < timeout.tv_sec) ||
	      ((time_waited.tv_sec == timeout.tv_sec) &&
	       (time_waited.tv_usec < timeout.tv_usec)))
	    goto send_again;
	  return (cu->cu_error.re_status = RPC_TIMEDOUT);

	  /*
	   * buggy in other cases because time_waited is not being
	   * updated.
	   */
	case -1:
	  if (errno == EINTR)
	    continue;
	  cu->cu_error.re_errno = errno;
	  return (cu->cu_error.re_status = RPC_CANTRECV);
	}
#ifdef IP_RECVERR
      if (fd.revents & POLLERR)
	{
	  struct msghdr msg;
	  struct cmsghdr *cmsg;
	  struct sock_extended_err *e;
	  struct sockaddr_in err_addr;
	  struct iovec iov;
	  char *cbuf = malloc (outlen + 256);
	  int ret;

	  if (cbuf == NULL)
	    {
	      cu->cu_error.re_errno = errno;
	      return (cu->cu_error.re_status = RPC_CANTRECV);
	    }

	  iov.iov_base = cbuf + 256;
	  iov.iov_len = outlen;
	  msg.msg_name = (void *) &err_addr;
	  msg.msg_namelen = sizeof (err_addr);
	  msg.msg_iov = &iov;
	  msg.msg_iovlen = 1;
	  msg.msg_flags = 0;
	  msg.msg_control = cbuf;
	  msg.msg_controllen = 256;
	  ret = __recvmsg (cu->cu_sock, &msg, MSG_ERRQUEUE);
	  if (ret >= 0
	      && memcmp (cbuf + 256, cu->cu_outbuf, ret) == 0
	      && (msg.msg_flags & MSG_ERRQUEUE)
	      && ((msg.msg_namelen == 0
		   && ret >= 12)
		  || (msg.msg_namelen == sizeof (err_addr)
		      && err_addr.sin_family == AF_INET
		      && memcmp (&err_addr.sin_addr, &cu->cu_raddr.sin_addr,
				 sizeof (err_addr.sin_addr)) == 0
		      && err_addr.sin_port == cu->cu_raddr.sin_port)))
	    for (cmsg = CMSG_FIRSTHDR (&msg); cmsg;
		 cmsg = CMSG_NXTHDR (&msg, cmsg))
	      if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
		{
		  free (cbuf);
		  e = (struct sock_extended_err *) CMSG_DATA(cmsg);
		  cu->cu_error.re_errno = e->ee_errno;
		  return (cu->cu_error.re_status = RPC_CANTRECV);
		}
	  free (cbuf);
	}
#endif
      do
	{
	  fromlen = sizeof (struct sockaddr);
	  inlen = __recvfrom (cu->cu_sock, cu->cu_inbuf,
			      (int) cu->cu_recvsz, MSG_DONTWAIT,
			      (struct sockaddr *) &from, &fromlen);
	}
      while (inlen < 0 && errno == EINTR);
      if (inlen < 0)
	{
	  if (errno == EWOULDBLOCK)
	    continue;
	  cu->cu_error.re_errno = errno;
	  return (cu->cu_error.re_status = RPC_CANTRECV);
	}
      if (inlen < 4)
	continue;

      /* see if reply transaction id matches sent id.
	Don't do this if we only wait for a replay */
      if (xargs != NULL
	  && memcmp (cu->cu_inbuf, cu->cu_outbuf, sizeof (u_int32_t)) != 0)
	continue;
      /* we now assume we have the proper reply */
      break;
    }

  /*
   * now decode and validate the response
   */
  xdrmem_create (&reply_xdrs, cu->cu_inbuf, (u_int) inlen, XDR_DECODE);
  ok = xdr_replymsg (&reply_xdrs, &reply_msg);
  /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
  if (ok)
    {
      _seterr_reply (&reply_msg, &(cu->cu_error));
      if (cu->cu_error.re_status == RPC_SUCCESS)
	{
	  if (!AUTH_VALIDATE (cl->cl_auth,
			      &reply_msg.acpted_rply.ar_verf))
	    {
	      cu->cu_error.re_status = RPC_AUTHERROR;
	      cu->cu_error.re_why = AUTH_INVALIDRESP;
	    }
	  if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
	    {
	      xdrs->x_op = XDR_FREE;
	      (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));
	    }
	}			/* end successful completion */
      else
	{
	  /* maybe our credentials need to be refreshed ... */
	  if (nrefreshes > 0 && AUTH_REFRESH (cl->cl_auth))
	    {
	      nrefreshes--;
	      goto call_again;
	    }
	}			/* end of unsuccessful completion */
    }				/* end of valid reply message */
  else
    {
      cu->cu_error.re_status = RPC_CANTDECODERES;
    }
  return cu->cu_error.re_status;
}