예제 #1
0
/* This is the server process request loop. The server process loop
 * becomes a listener thread when rxi_ServerProc returns, and stays
 * listener thread until rxi_ListenerProc returns. */
void *
rx_ServerProc(void * unused)
{
    osi_socket sock;
    int threadID;
    struct rx_call *newcall = NULL;
    fd_set *rfds;

    if (!(rfds = IOMGR_AllocFDSet())) {
	osi_Panic("rxi_ListenerProc: no fd_sets!\n");
    }

    rxi_MorePackets(rx_maxReceiveWindow + 2);	/* alloc more packets */
    rxi_dataQuota += rx_initSendWindow;	/* Reserve some pkts for hard times */
    /* threadID is used for making decisions in GetCall.  Get it by bumping
     * number of threads handling incoming calls */
    threadID = rxi_availProcs++;

    while (1) {
	sock = OSI_NULLSOCKET;
	rxi_ServerProc(threadID, newcall, &sock);
	/* assert(sock != OSI_NULLSOCKET); */
	newcall = NULL;
	rxi_ListenerProc(rfds, &threadID, &newcall);
	/* assert(threadID != -1); */
	/* assert(newcall != NULL); */
    }
    /* not reached */
    return NULL;
}
예제 #2
0
/* This is the listener process request loop. The listener process loop
 * becomes a server thread when rxi_ListenerProc returns, and stays
 * server thread until rxi_ServerProc returns. */
static void *
rx_ListenerProc(void *dummy)
{
    int threadID;
    osi_socket sock;
    struct rx_call *newcall;
    fd_set *rfds;

    if (!(rfds = IOMGR_AllocFDSet())) {
	osi_Panic("rx_ListenerProc: no fd_sets!\n");
    }

    while (1) {
	newcall = NULL;
	threadID = -1;
	rxi_ListenerProc(rfds, &threadID, &newcall);
	/* assert(threadID != -1); */
	/* assert(newcall != NULL); */
	sock = OSI_NULLSOCKET;
	rxi_ServerProc(threadID, newcall, &sock);
	/* assert(sock != OSI_NULLSOCKET); */
    }
    /* not reached */
    return NULL;
}
예제 #3
0
/*
 * Simulate a blocking sendmsg on the non-blocking socket.
 * It's non blocking because it was set that way for recvmsg.
 */
int
rxi_Sendmsg(osi_socket socket, struct msghdr *msg_p, int flags)
{
    fd_set *sfds = (fd_set *) 0;
    while (sendmsg(socket, msg_p, flags) == -1) {
	int err;
	rx_stats.sendSelects++;

	if (!sfds) {
	    if (!(sfds = IOMGR_AllocFDSet())) {
		(osi_Msg "rx failed to alloc fd_set: ");
		perror("rx_sendmsg");
		return -1;
	    }
	    FD_SET(socket, sfds);
	}
#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU)
	while((rxi_HandleSocketError(socket)) > 0)
	  ;
#endif
#ifdef AFS_NT40_ENV
	if (WSAGetLastError())
#elif defined(AFS_LINUX22_ENV)
	/* linux unfortunately returns ECONNREFUSED if the target port
	 * is no longer in use */
	/* and EAGAIN if a UDP checksum is incorrect */
	if (errno != EWOULDBLOCK && errno != ENOBUFS && errno != ECONNREFUSED
	    && errno != EAGAIN)
#else
	if (errno != EWOULDBLOCK && errno != ENOBUFS)
#endif
	{
	    (osi_Msg "rx failed to send packet: ");
	    perror("rx_sendmsg");
#ifndef AFS_NT40_ENV
            if (errno > 0)
              return -errno;
#else
            if (WSAGetLastError() > 0)
              return -WSAGetLastError();
#endif
	    return -1;
	}
	while ((err = select(socket + 1, 0, sfds, 0, 0)) != 1) {
	    if (err >= 0 || errno != EINTR)
		osi_Panic("rxi_sendmsg: select error %d.%d", err, errno);
	}
    }
    if (sfds)
	IOMGR_FreeFDSet(sfds);
    return 0;
}
예제 #4
0
void
handleWrite(clientHandle_t * ch, selcmd_t * sc)
{
    int i;
    fd_set *rfds, *wfds, *efds;
    char *buf;
    int code;
    int scode;
    char c;
    int nbytes;

    rfds = IOMGR_AllocFDSet();
    wfds = IOMGR_AllocFDSet();
    efds = IOMGR_AllocFDSet();
    assert(rfds && wfds && efds);

    if (sc->sc_delay > 0) {
	IOMGR_Sleep(sc->sc_delay);
    }

    Log("(handleWrite 0x%x) waking after %d second sleep.\n", ch->ch_pid,
	sc->sc_delay);

    if (sc->sc_flags & SC_WAIT_OOB)
	sendOOB(ch->ch_fd);

    buf = (char *)malloc(sc->sc_info);
    assert(buf);
    i = 0;

    while (1) {
	FD_ZERO(rfds);
	FD_SET(ch->ch_fd, rfds);
	FD_ZERO(efds);
	FD_SET(ch->ch_fd, efds);
	FD_ZERO(wfds);
	scode =
	    IOMGR_Select(ch->ch_fd + 1, rfds, wfds, efds,
			 (struct timeval *)0);
	assert(scode > 0);

	if (FD_ISSET(ch->ch_fd, rfds)) {

	    assert(i < sc->sc_info);

	    code = read(ch->ch_fd, &buf[i], 1);
	    i++;
	    write_I++;
	    if (code != 1) {
		Log("code =%d\n", code);
		assert(code == 1);
	    }

	    /* Test for valid fds */
	    assertNullFDSet(ch->ch_fd, rfds);
	    assertNullFDSet(-1, wfds);
	    assertNullFDSet(-1, efds);
	    if (c == END_DATA || i >= sc->sc_info) {
		break;
	    }
	}
    }
    Log("Read %d bytes of data.\n", sc->sc_info);
    nbytes = write(ch->ch_fd, buf, sc->sc_info);
    assert(nbytes == sc->sc_info);
    Log("Wrote data back to client.\n");
    IOMGR_FreeFDSet(rfds);
    IOMGR_FreeFDSet(wfds);
    IOMGR_FreeFDSet(efds);
}
예제 #5
0
main(int ac, char **av)
{
    int i;
    int on = 1;
    short port = -1;		/* host order. */
    int setFD = 0;
    struct sockaddr_in saddr;
    int acceptFD;
    clientHandle_t *clientHandle;
    int code;
    int addr_len;
    PROCESS pid;
    fd_set *rfds, *wfds, *efds;
    int sockFD;

    program = av[0];

    if (ac < 2)
	Usage();

/*    lwp_debug = 1; */

    signal(SIGIO, sigIO);


    for (i = 1; i < ac; i++) {
	if (!strcmp("-fd", av[i])) {
	    if (++i >= ac) {
		printf("Missing number for -fd option.\n");
		Usage();
	    }
	    setFD = atoi(av[i]);
	    if (setFD <= 2) {
		printf("%d: file descriptor must be at least 3.\n", setFD);
		Usage();
	    }
	} else {
	    if (port == -1) {
		port = atoi(av[i]);
		if (port <= 0) {
		    printf("%s: port must be at least 1\n", av[i]);
		    Usage();
		}
	    } else {
		printf("%s: Unknown argument.\n", av[i]);
	    }
	}
    }

    if (port == -1) {
	printf("Missing port.\n");
	Usage();
    }

    if (!setFD) {
	setFD = 31;
	printf("Using default socket of %d.\n", setFD);
    }

    OpenFDs(setFD);

    IOMGR_Initialize();

    /* Setup server processes */
    for (i = 0; i < MAX_THREADS; i++) {
	if (LWP_CreateProcess
	    (handleRequest, 32768, LWP_NORMAL_PRIORITY,
	     (char *)&clientHandles[i], "HandleRequestThread", &pid) < 0) {
	    printf("%s: Failed to start all LWP's\n", program);
	    exit(1);
	}
	clientHandles[i].ch_pid = pid;
    }


    sockFD = socket(AF_INET, SOCK_STREAM, 0);
    if (sockFD < 0) {
	perror("socket");
	exit(1);
    }
    Log("Using socket at file descriptor %d.\n", sockFD);

    if (setsockopt(sockFD, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))
	< 0) {
	perror("setsockopt: ");
	exit(1);
    }

    memset((void *)&saddr, 0, sizeof(saddr));

    saddr.sin_family = AF_INET;
    saddr.sin_port = ntohs(port);
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sockFD, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
	perror("bind: ");
	exit(1);
    }


    rfds = IOMGR_AllocFDSet();
    wfds = IOMGR_AllocFDSet();
    efds = IOMGR_AllocFDSet();
    if (!rfds || !wfds || !efds) {
	printf("main: Could not alloc fd_set's.\n");
	exit(1);
    }

    listen(sockFD, 100);


    while (1) {
	FD_ZERO(rfds);
	FD_ZERO(wfds);
	FD_ZERO(efds);
	FD_SET(sockFD, rfds);
	FD_SET(sockFD, efds);

	Log("Main - going to select.\n");
	code =
	    IOMGR_Select(sockFD + 1, rfds, wfds, efds, (struct timeval *)0);
	switch (code) {
	case 0:		/* Timer, can't happen here. */
	case -1:
	case -2:
	    Log("Oops! select returns %d!\n", code);
	    abort();
	default:
	    if (FD_ISSET(sockFD, efds)) {
		recvOOB(sockFD);
		assertNullFDSet(sockFD, rfds);
		assertNullFDSet(-1, wfds);
		assertNullFDSet(sockFD, efds);
	    }
	    if (FD_ISSET(sockFD, rfds)) {
		while (nThreads > MAX_THREADS) {
		    IOMGR_Sleep(1);
		}

		clientHandle = getClientHandle();

		addr_len = sizeof(clientHandle->ch_addr);
		clientHandle->ch_fd = accept(sockFD, (struct sockaddr *)
					     &clientHandle->ch_addr,
					     &addr_len);
		if (clientHandle->ch_fd < 0) {
		    perror("accept: ");
		    exit(1);
		}

		Log("Main - signalling LWP 0x%x\n", &clientHandle->ch_state);
		LWP_NoYieldSignal(&clientHandle->ch_state);
		assertNullFDSet(sockFD, rfds);
		assertNullFDSet(-1, wfds);
		assertNullFDSet(-1, efds);
		break;
	    }
	    Die(1, "(main) No data to read.\n");
	}
    }
}
예제 #6
0
파일: selclient.c 프로젝트: adeason/openafs
void
sendTest(int sockFD, int delay, int reqOOB, int size)
{
    char *buf, *bufTest;
    fd_set *rfds, *wfds, *efds;
    int i, j;
    int nbytes, code;
    selcmd_t selCmd;
    time_t stime, etime;

    buf = (char *)malloc(size);
    assert(buf);
    bufTest = (char *)malloc(size);
    assert(bufTest);

    for (j = i = 0; i < size; i++, j++) {
	if (j == END_DATA)
	    j++;
	if (j > 255)
	    j = 0;
	buf[i] = (char)j;
    }

    selCmd.sc_cmd = SC_WRITE;
    selCmd.sc_info = size;
    selCmd.sc_delay = delay;
    selCmd.sc_flags = SC_WAIT_ONLY;

    nbytes = write(sockFD, (char *)&selCmd, sizeof(selCmd));
    assert(nbytes == sizeof(selCmd));

    Log("Starting to write %d bytes.\n", size);
    if (!delay) {
	nbytes = write(sockFD, buf, size);
	assert(nbytes == size);
    } else {
	rfds = IOMGR_AllocFDSet();
	wfds = IOMGR_AllocFDSet();
	efds = IOMGR_AllocFDSet();
	if (!rfds || !wfds || !efds) {
	    printf("%s: Could not allocate all fd_sets.\n", program);
	    exit(1);
	}

	for (writeIndex = i = 0; i < size; writeIndex++, i++) {
	    FD_ZERO(rfds);
	    FD_ZERO(wfds);
	    FD_ZERO(efds);
	    FD_SET(sockFD, wfds);
	    FD_SET(sockFD, efds);
	    (void)time(&stime);
	    code =
		IOMGR_Select(sockFD + 1, rfds, wfds, efds,
			     (struct timeval *)NULL);
	    assert(code > 0);

	    if (FD_ISSET(sockFD, wfds)) {
		(void)time(&etime);
		if (etime - stime > 1) {
		    Log("Waited %d seconds to write at offset %d.\n",
			etime - stime, i);
		}
		stime = etime;
		nbytes = write(sockFD, &buf[i], 1);
		(void)time(&etime);
		if (etime - stime > 1) {
		    Log("Waited %d seconds IN write.\n", etime - stime);
		}
		assert(nbytes == 1);
		FD_CLR(sockFD, wfds);
	    }
	    assertNullFDSet(0, rfds);
	    assertNullFDSet(0, wfds);
	    assertNullFDSet(0, efds);
	}
    }

    Log("Wrote %d bytes.\n", size);
    i = 0;
    while (i < size) {
	nbytes = read(sockFD, &bufTest[i], size);
	i += nbytes;
    }
    Log("Read %d bytes.\n", size);

    assert(memcmp(buf, bufTest, size) == 0);
    Log("Compared %d bytes.\n", size);
}