Exemple #1
0
static void PR_CALLBACK reader(void *arg)
{
	PRUintn	i = 0;
	size_t	nbytes;
	
	do {
		(void) PR_WaitSem(emptyBufs);
		nbytes = dread(0, buf[i].data, BSIZE);
		buf[i].nbytes = nbytes;
		PR_PostSem(fullBufs);
		i = (i + 1) % 2;
	} while (nbytes > 0);
}
Exemple #2
0
static void writer(void)
{
	PRUintn	i = 0;
	size_t	nbytes;
	
	do {
		(void) PR_WaitSem(fullBufs);
		nbytes = buf[i].nbytes;
		if (nbytes > 0) {
			nbytes = dwrite(1, buf[i].data, nbytes);
			PR_PostSem(emptyBufs);
			i = (i + 1) % 2;
		}
	} while (nbytes > 0);
}
static void PR_CALLBACK writer(void *arg)
{
	PRUintn	i = 0;
	PRInt32	nbytes;
	
	do {
		(void) PR_WaitSem(fullBufs);
		nbytes = buf[i].nbytes;
		if (nbytes > 0) {
			nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes);
			PR_PostSem(emptyBufs);
			i = (i + 1) % 2;
		}
	} while (nbytes > 0);
}
static void PR_CALLBACK reader(void *arg)
{
	PRUintn	i = 0;
	PRInt32	nbytes;
	
	do {
		(void) PR_WaitSem(emptyBufs);
		nbytes = PR_Read((PRFileDesc*)arg, buf[i].data, BSIZE);
		if (nbytes >= 0) {
			buf[i].nbytes = nbytes;
			PR_PostSem(fullBufs);
			i = (i + 1) % 2;
		}
	} while (nbytes > 0);
}
Exemple #5
0
/*
 * UDP Server
 *    Server Thread
 *    Bind an address to a socket, read data from clients and send data
 *    back to clients
 */
static void PR_CALLBACK
UDP_Server(void *arg)
{
    Server_Param *sp = (Server_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf;
    PRNetAddr netaddr;
    PRInt32 bytes, i, rv;


    bytes = sp->datalen;
    /*
     * Create a udp socket
     */
    if ((sockfd = PR_NewUDPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
        failed_already=1;
        return;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.port = PR_htons(UDP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        failed_already=1;
        return;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        return;
    }
    if (netaddr.inet.port != PR_htons(UDP_SERVER_PORT)) {
        fprintf(stderr,"prsocket_test: ERROR - tried to bind to UDP "
            "port %hu, but was bound to port %hu\n",
            UDP_SERVER_PORT, PR_ntohs(netaddr.inet.port));
        failed_already=1;
        return;
    }

    DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    udp_server_addr = netaddr;

    /*
     * We can't use the IP address returned by PR_GetSockName in
         * netaddr.inet.ip because netaddr.inet.ip is returned
         * as 0 (= INADDR_ANY).
     */

    udp_server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'udp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    bytes = sp->datalen;
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    /*
     * Receive datagrams from clients and send them back, unmodified, to the
     * clients
     */
    memset(&netaddr, 0 , sizeof(netaddr));
    for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
        DPRINTF(("UDP_Server: calling PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
            in_buf->data[0]));

        rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
            PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("UDP_Server: PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
            in_buf->data[0]));
        if (rv != bytes) {
            return;
        }
        rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
            PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
    }

    PR_DELETE(in_buf);

    /*
     * Decrement exit_counter and notify parent thread
     */
    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));
}
Exemple #6
0
/*
 * TCP Server
 *    Server Thread
 *    Bind an address to a socket and listen for incoming connections
 *    Start a Serve_Client thread for each incoming connection.
 */
static void PR_CALLBACK
TCP_Server(void *arg)
{
    PRThread *t;
    Server_Param *sp = (Server_Param *) arg;
    Serve_Client_Param *scp;
    PRFileDesc *sockfd, *newsockfd;
    PRNetAddr netaddr;
    PRInt32 i;
    /*
     * Create a tcp socket
     */
    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        goto exit;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        failed_already=1;
        goto exit;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
        failed_already=1;
        goto exit;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        goto exit;
    }

    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    tcp_server_addr.inet.family = netaddr.inet.family;
    tcp_server_addr.inet.port = netaddr.inet.port;
    tcp_server_addr.inet.ip = netaddr.inet.ip;

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'tcp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {

        if ((newsockfd = PR_Accept(sockfd, &netaddr,
            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
            fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n");
            goto exit;
        }
        scp = PR_NEW(Serve_Client_Param);
        if (scp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            goto exit;
        }

        /*
         * Start a Serve_Client thread for each incoming connection
         */
        scp->sockfd = newsockfd;
        scp->datalen = sp->datalen;

        t = PR_CreateThread(PR_USER_THREAD,
            Serve_Client, (void *)scp, 
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD,
            0);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            goto exit;
        }
        DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t));
    }

exit:
    if (sockfd) {
        PR_Close(sockfd);
    }

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
}
Exemple #7
0
/*
 * TransmitFile Server
 *    Server Thread
 *    Bind an address to a socket and listen for incoming connections
 *    Create worker threads to service clients
 */
static void
TransmitFile_Server(void *arg)
{
    PRThread **t = NULL;  /* an array of PRThread pointers */
    Server_Param *sp = (Server_Param *) arg;
    Serve_Client_Param *scp;
    PRFileDesc *sockfd = NULL, *newsockfd;
    PRNetAddr netaddr;
    PRInt32 i;
    PRThreadScope scope;

    t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *));
    if (t == NULL) {
        fprintf(stderr, "prsocket_test: run out of memory\n");
        failed_already=1;
        goto exit;
    }
    /*
     * Create a tcp socket
     */
    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        failed_already=1;
        goto exit;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = AF_INET;
    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        failed_already=1;
        perror("PR_Bind");
        goto exit;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
        failed_already=1;
        goto exit;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,
            "prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        goto exit;
    }

    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    tcp_server_addr.inet.family = netaddr.inet.family;
    tcp_server_addr.inet.port = netaddr.inet.port;
    tcp_server_addr.inet.ip = netaddr.inet.ip;

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'tcp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    for (i = 0; i < num_transmitfile_clients ; i++) {

        if ((newsockfd = PR_Accept(sockfd, &netaddr,
            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
            fprintf(stderr,
                "prsocket_test: ERROR - PR_Accept failed\n");
            failed_already=1;
            goto exit;
        }
        scp = PR_NEW(Serve_Client_Param);
        if (scp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            failed_already=1;
            goto exit;
        }

        /*
         * Start a Serve_Client thread for each incoming connection
         */
        scp->sockfd = newsockfd;
        scp->datalen = sp->datalen;

        /*
         * create LOCAL and GLOBAL threads alternately
         */
        if (i & 1)
            scope = PR_LOCAL_THREAD;
        else
            scope = PR_GLOBAL_THREAD;
        t[i] = PR_CreateThread(PR_USER_THREAD,
            Serve_TransmitFile_Client, (void *)scp, 
            PR_PRIORITY_NORMAL,
            scope,
            PR_JOINABLE_THREAD,
            0);
        if (t[i] == NULL) {
            fprintf(stderr,
                "prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            goto exit;
        }
        DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t));
    }

    /*
     * Wait for all the worker threads to end, so that we know
     * they are no longer using the small and large file fd's.
     */

    for (i = 0; i < num_transmitfile_clients; i++) {
        PR_JoinThread(t[i]);
    }

exit:
    if (t) {
        PR_DELETE(t);
    }
    if (sockfd) {
        PR_Close(sockfd);
    }

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
}