Ejemplo n.º 1
0
static int IOLabelWriteLine( int fd, int rdwr, void *data )
{
    IOLabel *label = (IOLabel *)data;
    char buf[1024], *p;
    int n;

    MPIE_SYSCALL(n,read,( fd, buf, 1024 ));
    if (n == 0) {
	/* If read blocks, then returning a 0 is end-of-file */
	return 1;  /* ? EOF */
    }

    p = buf;
    while (n > 0) {
	int c;
	if (label->lastNL) {
	    if (label->label[0]) {
		fprintf( label->dest, "%s", label->label );
	    }
	    label->lastNL = 0;
	}
	c = *p++; n--;
	if (fputc( c, label->dest ) != c) return 1;
	label->lastNL = (c == '\n');
    }
    return 0;
}
Ejemplo n.º 2
0
/*@
  MPIE_IOLoop - Handle all registered I/O

Input Parameters:
.  timeoutSeconds - Seconds until this routine should return with a
   timeout error.  If negative, no timeout.  If 0, return immediatedly
   after a nonblocking check for I/O.

   Return Value:
   Returns zero on success.  Returns 'IOLOOP_TIMEOUT' if the timeout
   is reached and 'IOLOOP_ERROR' on other errors.
@*/
int MPIE_IOLoop(int timeoutSeconds)
{
    int i, maxfd, fd, nfds, rc = 0, rc2;
    fd_set readfds, writefds;
    int (*handler) (int, int, void *);
    struct timeval tv;

    /* Loop on the fds, with the timeout */
    TimeoutInit(timeoutSeconds);
    while (1) {
        tv.tv_sec = TimeoutGetRemaining();
        tv.tv_usec = 0;
        /* Determine the active FDs */
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        /* maxfd is the maximum active fd */
        maxfd = -1;
        for (i = 0; i <= maxFD; i++) {
            if (handlesByFD[i].handler) {
                fd = handlesByFD[i].fd;
                if (handlesByFD[i].rdwr & IO_READ) {
                    FD_SET(fd, &readfds);
                    maxfd = i;
                }
                if (handlesByFD[i].rdwr & IO_WRITE) {
                    FD_SET(fd, &writefds);
                    maxfd = i;
                }
            }
        }
        if (maxfd < 0)
            break;

        /* DBG_PRINTF(("Calling select with readfds = %x writefds = %x\n", */
        /*          *(int *)&readfds, *(int*)&writefds)); */
        MPIE_SYSCALL(nfds, select, (maxfd + 1, &readfds, &writefds, 0, &tv));
        if (nfds < 0 && (errno == EINTR || errno == 0)) {
            /* Continuing through EINTR */
            /* We allow errno == 0 as a synonym for EINTR.  We've seen this
             * on Solaris; in addition, we set errno to 0 after a failed
             * waitpid in the process routines, and if the OS isn't careful,
             * the value of errno may get ECHILD instead of EINTR when the
             * signal handler returns (we suspect Linux of this problem),
             * which is why we have the signal handler in process.c reset
             * errno to 0 (we may need to allow ECHILD here (!)) */
            /* FIXME: an EINTR may also mean that a process has exited
             * (SIGCHILD).  If all processes have exited, we may want to
             * exit */
            DBG_PRINTF(("errno = EINTR in select\n"));
            continue;
        }
        if (nfds < 0) {
            /* Serious error */
            MPL_internal_sys_error_printf("select", errno, 0);
            break;
        }
        if (nfds == 0) {
            /* Timeout from select */
            DBG_PRINTF(("Timeout in select\n"));
            return IOLOOP_TIMEOUT;
        }
        /* nfds > 0 */
        DBG_PRINTF(("Found some fds to process (n = %d)\n", nfds));
        for (fd = 0; fd <= maxfd; fd++) {
            if (FD_ISSET(fd, &writefds)) {
                handler = handlesByFD[fd].handler;
                if (handler) {
                    rc = (*handler) (fd, IO_WRITE, handlesByFD[fd].extra_data);
                }
                if (rc == 1) {
                    /* EOF? */
                    MPIE_SYSCALL(rc2, close, (fd));
                    handlesByFD[fd].rdwr = 0;
                    FD_CLR(fd, &writefds);
                }
            }
            if (FD_ISSET(fd, &readfds)) {
                handler = handlesByFD[fd].handler;
                if (handler) {
                    rc = (*handler) (fd, IO_READ, handlesByFD[fd].extra_data);
                }
                if (rc == 1) {
                    /* EOF? */
                    MPIE_SYSCALL(rc2, close, (fd));
                    handlesByFD[fd].rdwr = 0;
                    FD_CLR(fd, &readfds);
                }
            }
        }
    }
    DBG_PRINTF(("Returning from IOLOOP handler\n"));
    return 0;
}
Ejemplo n.º 3
0
/* IO Handler for the listen socket
   Respond to a connection request by creating a new socket, which is
   then registered.
   Initialize the startup handshake.
 */
int PMIServAcceptFromPort( int fd, int rdwr, void *data )
{
    int             newfd;
    struct sockaddr sock;
    socklen_t       addrlen = sizeof(sock);
    int             id;
    ProcessUniverse *univ = (ProcessUniverse *)data;
    ProcessWorld    *pWorld = univ->worlds;
    ProcessApp      *app;

    /* Get the new socket */
    MPIE_SYSCALL(newfd,accept,( fd, &sock, &addrlen ));
    DBG_PRINTF(("Acquired new socket in accept (fd = %d)\n", newfd ));
    if (newfd < 0) {
	DBG(perror("Error on accept: " ));
	return newfd;
    }

#ifdef FOO
    /* Mark this fd as non-blocking */
    flags = fcntl( newfd, F_GETFL, 0 );
    if (flags >= 0) {
	flags |= O_NDELAY;
	fcntl( newfd, F_SETFL, flags );
    }
#endif
    /* Make sure that exec'd processes don't get this fd */
    fcntl( newfd, F_SETFD, FD_CLOEXEC );

    /* Find the matching process.  Do this by reading from the socket and 
       getting the id value with which process was created. */
    id = PMI_Init_port_connection( newfd );
    if (id >= 0) {
	/* find the matching entry */
	ProcessState *pState = 0;
	int           nSoFar = 0;
	PMIProcess   *pmiprocess;

	/* This code assigns processes to the states in a pWorld
	   by using the id as the rank, and finding the corresponding
	   process among the ranks */
	while (pWorld) {
	    app = pWorld->apps;
	    while (app) {
		if (app->nProcess > id - nSoFar) {
		    /* Found the matching app */
		    pState = app->pState + (id - nSoFar);
		    break;
		}
		else {
		    nSoFar += app->nProcess;
		}
		app = app->nextApp;
	    }
	    pWorld = pWorld->nextWorld;
	}
	if (!pState) {
	    /* We have a problem */
	    MPL_error_printf( "Unable to find process with PMI_ID = %d in the universe", id );
	    return -1;
	}

	/* Now, initialize the connection */
	/* Create the new process structure (see PMISetupFinishInServer
	   for this step when a pre-existing FD is used */
	DBG_PRINTF( ("Server connection to id = %d on fd %d\n", id, newfd ));
	pmiprocess = PMISetupNewProcess( newfd, pState );
	PMI_Init_remote_proc( newfd, pmiprocess );
	MPIE_IORegister( newfd, IO_READ, PMIServHandleInput, 
			 pmiprocess );
    }
    else {
	/* Error, the id should never be less than zero or unset */
	/* An alternative would be to dynamically assign the ranks
	   as processes come in (but we'd still need to use the 
	   PMI_ID to identify the ProcessApp) */
	DBG_PRINTF(("Found an invalid id\n" ));
	return -1;
    }

    /* Return success. */
    return 0;
}