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

📄 cltsrv.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    char buffer[1024];    PRFileDesc *file = NULL;    PRThread * me = PR_CurrentThread();    PRInt32 bytes, descbytes, netbytes, filebytes = 0;    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT);    TEST_LOG(        cltsrv_log_file, TEST_LOG_VERBOSE,        ("\tProcessRequest(0x%p): receiving desciptor\n", me));    bytes = PR_Recv(        fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout);    if (-1 == bytes)    {        rv = PR_FAILURE;        if (Aborted(rv)) goto exit;        if (PR_IO_TIMEOUT_ERROR == PR_GetError())        {            TEST_LOG(                cltsrv_log_file, TEST_LOG_ERROR,                ("\tProcessRequest(0x%p): receive timeout\n", me));        }        goto exit;    }    if (0 == bytes)    {        rv = PR_FAILURE;        TEST_LOG(            cltsrv_log_file, TEST_LOG_ERROR,            ("\tProcessRequest(0x%p): unexpected end of file\n", me));        goto exit;    }    descbytes = PR_ntohl(descriptor->size);    TEST_ASSERT(sizeof(*descriptor) == bytes);    TEST_LOG(        cltsrv_log_file, TEST_LOG_VERBOSE,         ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",        me, descbytes, descriptor->filename));    file = PR_Open(        descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666);    if (NULL == file)    {        rv = PR_FAILURE;        if (Aborted(rv)) goto aborted;        if (PR_IO_TIMEOUT_ERROR == PR_GetError())        {            TEST_LOG(                cltsrv_log_file, TEST_LOG_ERROR,                ("\tProcessRequest(0x%p): open file timeout\n", me));            goto aborted;        }    }    TEST_ASSERT(NULL != file);    filebytes = 0;    while (filebytes < descbytes)    {        netbytes = sizeof(buffer);        if ((descbytes - filebytes) < netbytes)            netbytes = descbytes - filebytes;        TEST_LOG(            cltsrv_log_file, TEST_LOG_VERBOSE,            ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes));        bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);        if (-1 == bytes)        {            rv = PR_FAILURE;            if (Aborted(rv)) goto aborted;            if (PR_IO_TIMEOUT_ERROR == PR_GetError())            {                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tProcessRequest(0x%p): receive data timeout\n", me));                goto aborted;            }            /*             * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)             * on NT here.  This is equivalent to ECONNRESET on Unix.             *     -wtc             */            TEST_LOG(                cltsrv_log_file, TEST_LOG_WARNING,                ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",                me, PR_GetError(), PR_GetOSError()));            goto aborted;        }        if(0 == bytes)        {            TEST_LOG(                cltsrv_log_file, TEST_LOG_WARNING,                ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me));            rv = PR_FAILURE;            goto aborted;        }        filebytes += bytes;        netbytes = bytes;        /* The byte count for PR_Write should be positive */        MY_ASSERT(netbytes > 0);        TEST_LOG(            cltsrv_log_file, TEST_LOG_VERBOSE,            ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes));        bytes = PR_Write(file, buffer, netbytes);        if (netbytes != bytes)        {            rv = PR_FAILURE;            if (Aborted(rv)) goto aborted;            if (PR_IO_TIMEOUT_ERROR == PR_GetError())            {                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tProcessRequest(0x%p): write file timeout\n", me));                goto aborted;            }        }        TEST_ASSERT(bytes > 0);    }    PR_Lock(server->ml);    server->operations += 1;    server->bytesTransferred += filebytes;    PR_Unlock(server->ml);    rv = PR_Close(file);    if (Aborted(rv)) goto aborted;    TEST_ASSERT(PR_SUCCESS == rv);    file = NULL;    TEST_LOG(        cltsrv_log_file, TEST_LOG_VERBOSE,        ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename));    file = PR_Open(descriptor->filename, PR_RDONLY, 0);    if (NULL == file)    {        rv = PR_FAILURE;        if (Aborted(rv)) goto aborted;        if (PR_IO_TIMEOUT_ERROR == PR_GetError())        {            TEST_LOG(                cltsrv_log_file, TEST_LOG_ERROR,                ("\t\tProcessRequest(0x%p): open file timeout\n",                PR_CurrentThread()));            goto aborted;        }        TEST_LOG(            cltsrv_log_file, TEST_LOG_ERROR,            ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",            me, PR_GetError(), PR_GetOSError()));        goto aborted;    }    TEST_ASSERT(NULL != file);    netbytes = 0;    while (netbytes < descbytes)    {        filebytes = sizeof(buffer);        if ((descbytes - netbytes) < filebytes)            filebytes = descbytes - netbytes;        TEST_LOG(            cltsrv_log_file, TEST_LOG_VERBOSE,            ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes));        bytes = PR_Read(file, buffer, filebytes);        if (filebytes != bytes)        {            rv = PR_FAILURE;            if (Aborted(rv)) goto aborted;            if (PR_IO_TIMEOUT_ERROR == PR_GetError())                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tProcessRequest(0x%p): read file timeout\n", me));            else                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",                    me, PR_GetError(), PR_GetOSError()));            goto aborted;        }        TEST_ASSERT(bytes > 0);        netbytes += bytes;        filebytes = bytes;        TEST_LOG(            cltsrv_log_file, TEST_LOG_VERBOSE,            ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes));        bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);        if (filebytes != bytes)        {            rv = PR_FAILURE;            if (Aborted(rv)) goto aborted;            if (PR_IO_TIMEOUT_ERROR == PR_GetError())            {                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tProcessRequest(0x%p): send data timeout\n", me));                goto aborted;            }            break;        }       TEST_ASSERT(bytes > 0);    }        PR_Lock(server->ml);    server->bytesTransferred += filebytes;    PR_Unlock(server->ml);    rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);    if (Aborted(rv)) goto aborted;    rv = PR_Close(file);    if (Aborted(rv)) goto aborted;    TEST_ASSERT(PR_SUCCESS == rv);    file = NULL;aborted:    PR_ClearInterrupt();    if (NULL != file) PR_Close(file);    drv = PR_Delete(descriptor->filename);    TEST_ASSERT(PR_SUCCESS == drv);exit:    TEST_LOG(        cltsrv_log_file, TEST_LOG_VERBOSE,        ("\t\tProcessRequest(0x%p): Finished\n", me));    PR_DELETE(descriptor);#if defined(WIN95)    PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */#endif    return rv;}  /* ProcessRequest */static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool){    CSWorker_t *worker = PR_NEWZAP(CSWorker_t);    worker->server = server;    PR_INIT_CLIST(&worker->element);    worker->thread = PR_CreateThread(        PR_USER_THREAD, Worker, worker,        DEFAULT_SERVER_PRIORITY, thread_scope,        PR_UNJOINABLE_THREAD, 0);    if (NULL == worker->thread)    {        PR_DELETE(worker);        return PR_FAILURE;    }    TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS,         ("\tCreateWorker(0x%p): create new worker (0x%p)\n",        PR_CurrentThread(), worker->thread));    return PR_SUCCESS;}  /* CreateWorker */static void PR_CALLBACK Worker(void *arg){    PRStatus rv;    PRNetAddr from;    PRFileDesc *fd = NULL;    PRThread *me = PR_CurrentThread();    CSWorker_t *worker = (CSWorker_t*)arg;    CSServer_t *server = worker->server;    CSPool_t *pool = &server->pool;    TEST_LOG(        cltsrv_log_file, TEST_LOG_NOTICE,        ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1));    PR_Lock(server->ml);    PR_APPEND_LINK(&worker->element, &server->list);    pool->workers += 1;  /* define our existance */    while (cs_run == server->state)    {        while (pool->accepting >= server->workers.accepting)        {            TEST_LOG(                cltsrv_log_file, TEST_LOG_VERBOSE,                ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",                me, pool->accepting));            rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT);            if (Aborted(rv) || (cs_run != server->state))            {                TEST_LOG(                    cltsrv_log_file, TEST_LOG_NOTICE,                    ("\tWorker(0x%p): has been %s\n",                    me, (Aborted(rv) ? "interrupted" : "stopped")));                goto exit;            }        }         pool->accepting += 1;  /* how many are really in accept */        PR_Unlock(server->ml);        TEST_LOG(            cltsrv_log_file, TEST_LOG_VERBOSE,            ("\t\tWorker(0x%p): calling accept\n", me));        fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT);        PR_Lock(server->ml);                pool->accepting -= 1;        PR_NotifyCondVar(pool->acceptComplete);        if ((NULL == fd) && Aborted(PR_FAILURE))        {            if (NULL != server->listener)            {                PR_Close(server->listener);                server->listener = NULL;            }            goto exit;        }        if (NULL != fd)        {            /*            ** Create another worker of the total number of workers is            ** less than the minimum specified or we have none left in            ** accept() AND we're not over the maximum.            ** This sort of presumes that the number allowed in accept            ** is at least as many as the minimum. Otherwise we'll keep            ** creating new threads and deleting them soon after.            */            PRBool another =                ((pool->workers < server->workers.minimum) ||                ((0 == pool->accepting)                    && (pool->workers < server->workers.maximum))) ?                    PR_TRUE : PR_FALSE;            pool->active += 1;            PR_Unlock(server->ml);            if (another) (void)CreateWorker(server, pool);            rv = ProcessRequest(fd, server);            if (PR_SUCCESS != rv)                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tWorker(0x%p): server process ended abnormally\n", me));            (void)PR_Close(fd); fd = NULL;            PR_Lock(server->ml);            pool->active -= 1;        }    }exit:    PR_ClearInterrupt();        PR_Unlock(server->ml);    if (NULL != fd)    {        (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);        (void)PR_Close(fd);    }    TEST_LOG(        cltsrv_log_file, TEST_LOG_NOTICE,        ("\t\tWorker(0x%p): exiting [%u]\n", PR_CurrentThread(), pool->workers));    PR_Lock(server->ml);    pool->workers -= 1;  /* undefine our existance */    PR_REMOVE_AND_INIT_LINK(&worker->element);    PR_NotifyCondVar(pool->exiting);    PR_Unlock(server->ml);    PR_DELETE(worker);  /* destruction of the "worker" object */}  /* Worker */static void PR_CALLBACK Server(void *arg){    PRStatus rv;    PRNetAddr serverAddress;    PRThread *me = PR_CurrentThread();    CSServer_t *server = (CSServer_t*)arg;    PRSocketOptionData sockOpt;    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);    sockOpt.option = PR_SockOpt_Reuseaddr;    sockOpt.value.reuse_addr = PR_TRUE;    rv = PR_SetSocketOption(server->listener, &sockOpt);    TEST_ASSERT(PR_SUCCESS == rv);    memset(&serverAddress, 0, sizeof(serverAddress));	if (PR_AF_INET6 != domain)		rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);	else		rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT,													&serverAddress);    rv = PR_Bind(server->listener, &serverAddress);    TEST_ASSERT(PR_SUCCESS == rv);    rv = PR_Listen(server->listener, server->backlog);    TEST_ASSERT(PR_SUCCESS == rv);    server->started = PR_IntervalNow();    TimeOfDayMessage("Server started at", me);    PR_Lock(server->ml);    server->state = cs_run;    PR_NotifyCondVar(server->stateChange);    PR_Unlock(server->ml);    /*    ** Create the first worker (actually, a thread that accepts    ** connections and then processes the work load as needed).    ** From this point on, additional worker threads are created    ** as they are needed by existing worker threads.    */

⌨️ 快捷键说明

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