⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nblayer.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                break;            case xmt_send_debit:            case xmt_data:                my_flags = in_flags;            default: break;        }    }    else PR_ASSERT(!"How'd I get here?");    new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags);    if (verbosity > chatty)        PR_fprintf(            logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n",            in_flags, my_flags, *out_flags, new_flags);    return new_flags;}  /* MyPoll */static PRFileDesc * PR_CALLBACK MyAccept(    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout){    PRStatus rv;    PRFileDesc *newfd, *layer = fd;    PRFileDesc *newstack;    PRFilePrivate *newsecret;    PR_ASSERT(fd != NULL);    PR_ASSERT(fd->lower != NULL);    newstack = PR_NEW(PRFileDesc);    if (NULL == newstack)    {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return NULL;    }    newsecret = PR_NEW(PRFilePrivate);    if (NULL == newsecret)    {        PR_DELETE(newstack);        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return NULL;    }    *newstack = *fd;  /* make a copy of the accepting layer */    *newsecret = *fd->secret;    newstack->secret = newsecret;    newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);    if (NULL == newfd)    {        PR_DELETE(newsecret);        PR_DELETE(newstack);        return NULL;    }    /* this PR_PushIOLayer call cannot fail */    rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);    PR_ASSERT(PR_SUCCESS == rv);    return newfd;  /* that's it */}static PRInt32 PR_CALLBACK MyRecv(    PRFileDesc *fd, void *buf, PRInt32 amount,    PRIntn flags, PRIntervalTime timeout){    char *b;    PRInt32 rv;    PRFileDesc *lo = fd->lower;    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;    do    {        switch (mine->rcvstate)        {        case rcv_get_debit:            b = (char*)&mine->rcvreq;            mine->rcvreq = amount;            rv = lo->methods->recv(                lo, b + mine->rcvinprogress,                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);            if (0 == rv) goto closed;            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;            mine->rcvinprogress += rv;  /* accumulate the read */            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */            mine->rcvstate = rcv_send_credit;            mine->rcvinprogress = 0;        case rcv_send_credit:            b = (char*)&mine->rcvreq;            rv = lo->methods->send(                lo, b + mine->rcvinprogress,                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;            mine->rcvinprogress += rv;  /* accumulate the read */            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */            mine->rcvstate = rcv_data;            mine->rcvinprogress = 0;        case rcv_data:            b = (char*)buf;            rv = lo->methods->recv(                lo, b + mine->rcvinprogress,                mine->rcvreq - mine->rcvinprogress, flags, timeout);            if (0 == rv) goto closed;            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;            mine->rcvinprogress += rv;  /* accumulate the read */            if (mine->rcvinprogress < amount) break;  /* loop */            mine->rcvstate = rcv_get_debit;            mine->rcvinprogress = 0;            return mine->rcvreq;  /* << -- that's it! */        default:            break;        }    } while (-1 != rv);    return rv;closed:    mine->rcvinprogress = 0;    mine->rcvstate = rcv_get_debit;    return 0;}  /* MyRecv */static PRInt32 PR_CALLBACK MySend(    PRFileDesc *fd, const void *buf, PRInt32 amount,    PRIntn flags, PRIntervalTime timeout){    char *b;    PRInt32 rv;    PRFileDesc *lo = fd->lower;    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;    do    {        switch (mine->xmtstate)        {        case xmt_send_debit:            b = (char*)&mine->xmtreq;            mine->xmtreq = amount;            rv = lo->methods->send(                lo, b - mine->xmtinprogress,                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;            mine->xmtinprogress += rv;            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;            mine->xmtstate = xmt_recv_credit;            mine->xmtinprogress = 0;        case xmt_recv_credit:             b = (char*)&mine->xmtreq;             rv = lo->methods->recv(                lo, b + mine->xmtinprogress,                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;            mine->xmtinprogress += rv;            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;            mine->xmtstate = xmt_data;            mine->xmtinprogress = 0;        case xmt_data:            b = (char*)buf;            rv = lo->methods->send(                lo, b + mine->xmtinprogress,                mine->xmtreq - mine->xmtinprogress, flags, timeout);            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;            mine->xmtinprogress += rv;            if (mine->xmtinprogress < amount) break;            mine->xmtstate = xmt_send_debit;            mine->xmtinprogress = 0;            return mine->xmtreq;  /* <<-- That's the one! */        default:            break;        }    } while (-1 != rv);    return rv;}  /* MySend */static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta){    PRIntn verbage = (PRIntn)verbosity + delta;    if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;    else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;    return (Verbosity)verbage;}  /* ChangeVerbosity */PRIntn main(PRIntn argc, char **argv){    PRStatus rv;    PLOptStatus os;    PRFileDesc *client, *service;    PRNetAddr any_address;    const char *server_name = NULL;    const PRIOMethods *stubMethods;    PRThread *client_thread, *server_thread;    PRThreadScope thread_scope = PR_LOCAL_THREAD;    PRSocketOptionData socket_noblock, socket_nodelay;    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))    {        if (PL_OPT_BAD == os) continue;        switch (opt->option)        {        case 0:            server_name = opt->value;            break;        case 'd':  /* debug mode */            if (verbosity < noisy)                verbosity = ChangeVerbosity(verbosity, 1);            break;        case 'q':  /* debug mode */            if (verbosity > silent)                verbosity = ChangeVerbosity(verbosity, -1);            break;        case 'G':  /* use global threads */            thread_scope = PR_GLOBAL_THREAD;            break;        case 'C':  /* number of threads waiting */            major_iterations = atoi(opt->value);            break;        case 'c':  /* number of client threads */            minor_iterations = atoi(opt->value);            break;        case 'p':  /* default port */            default_port = atoi(opt->value);            break;        default:            break;        }    }    PL_DestroyOptState(opt);    PR_STDIO_INIT();    logFile = PR_GetSpecialFD(PR_StandardError);    identity = PR_GetUniqueIdentity("Dummy");    stubMethods = PR_GetDefaultIOMethods();    /*    ** The protocol we're going to implement is one where in order to initiate    ** a send, the sender must first solicit permission. Therefore, every    ** send is really a send - receive - send sequence.    */    myMethods = *stubMethods;  /* first get the entire batch */    myMethods.accept = MyAccept;  /* then override the ones we care about */    myMethods.recv = MyRecv;  /* then override the ones we care about */    myMethods.send = MySend;  /* then override the ones we care about */    myMethods.close = MyClose;  /* then override the ones we care about */    myMethods.poll = MyPoll;  /* then override the ones we care about */    if (NULL == server_name)        rv = PR_InitializeNetAddr(            PR_IpAddrLoopback, default_port, &server_address);    else    {        rv = PR_StringToNetAddr(server_name, &server_address);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_InitializeNetAddr(            PR_IpAddrNull, default_port, &server_address);    }    PR_ASSERT(PR_SUCCESS == rv);    socket_noblock.value.non_blocking = PR_TRUE;    socket_noblock.option = PR_SockOpt_Nonblocking;    socket_nodelay.value.no_delay = PR_TRUE;    socket_nodelay.option = PR_SockOpt_NoDelay;    /* one type w/o layering */    while (major_iterations-- > 0)    {        if (verbosity > silent)            PR_fprintf(logFile, "Beginning non-layered test\n");        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);        rv = PR_SetSocketOption(client, &socket_noblock);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_SetSocketOption(service, &socket_noblock);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_SetSocketOption(client, &socket_nodelay);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_SetSocketOption(service, &socket_nodelay);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);        server_thread = PR_CreateThread(            PR_USER_THREAD, Server, service,            PR_PRIORITY_HIGH, thread_scope,            PR_JOINABLE_THREAD, 16 * 1024);        PR_ASSERT(NULL != server_thread);        client_thread = PR_CreateThread(            PR_USER_THREAD, Client, client,            PR_PRIORITY_NORMAL, thread_scope,            PR_JOINABLE_THREAD, 16 * 1024);        PR_ASSERT(NULL != client_thread);        rv = PR_JoinThread(client_thread);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_JoinThread(server_thread);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);        if (verbosity > silent)            PR_fprintf(logFile, "Ending non-layered test\n");        /* with layering */        if (verbosity > silent)            PR_fprintf(logFile, "Beginning layered test\n");        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);        rv = PR_SetSocketOption(client, &socket_noblock);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_SetSocketOption(service, &socket_noblock);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_SetSocketOption(client, &socket_nodelay);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_SetSocketOption(service, &socket_nodelay);        PR_ASSERT(PR_SUCCESS == rv);        PushLayer(client);        PushLayer(service);        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);        server_thread = PR_CreateThread(            PR_USER_THREAD, Server, service,            PR_PRIORITY_HIGH, thread_scope,            PR_JOINABLE_THREAD, 16 * 1024);        PR_ASSERT(NULL != server_thread);        client_thread = PR_CreateThread(            PR_USER_THREAD, Client, client,            PR_PRIORITY_NORMAL, thread_scope,            PR_JOINABLE_THREAD, 16 * 1024);        PR_ASSERT(NULL != client_thread);        rv = PR_JoinThread(client_thread);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_JoinThread(server_thread);        PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv);        rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv);        if (verbosity > silent)            PR_fprintf(logFile, "Ending layered test\n");    }    return 0;}  /* main *//* nblayer.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -