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

📄 provider.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * * Notes: * [1] lth. The call to Sleep() is a hack to get the test case to run * on Windows 95. Without it, the test case fails with an error * WSAECONNRESET following a recv() call. The error is caused by the * server side thread termination without a shutdown() or closesocket() * call. Windows docmunentation suggests that this is predicted * behavior; that other platforms get away with it is ... serindipity. * The test case should shutdown() or closesocket() before * thread termination. I didn't have time to figure out where or how * to do it. The Sleep() call inserts enough delay to allow the * client side to recv() all his data before the server side thread * terminates. Whew! ... * ** Modification History: * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. *             The debug mode will print all of the printfs associated with this test. *             The regress mode will be the default mode. Since the regress tool limits *           the output to a one line status:PASS or FAIL,all of the printf statements *             have been handled with an if (debug_mode) statement.  */#include "prclist.h"#include "prcvar.h"#include "prerror.h"#include "prinit.h"#include "prinrval.h"#include "prio.h"#include "prlock.h"#include "prlog.h"#include "prtime.h"#include "prmem.h"#include "prnetdb.h"#include "prprf.h"#include "prthread.h"#include "pprio.h"#include "primpl.h"#include "plstr.h"#include "plerror.h"#include "plgetopt.h"#include <stdlib.h>#include <string.h>#if defined(XP_UNIX)#include <math.h>#endif#ifdef XP_MAC#include "prlog.h"#define printf PR_LogPrint#endif/*** This is the beginning of the test*/#define RECV_FLAGS 0#define SEND_FLAGS 0#define BUFFER_SIZE 1024#define DEFAULT_BACKLOG 5#define DEFAULT_PORT 13000#define DEFAULT_CLIENTS 1#define ALLOWED_IN_ACCEPT 1#define DEFAULT_CLIPPING 1000#define DEFAULT_WORKERS_MIN 1#define DEFAULT_WORKERS_MAX 1#define DEFAULT_SERVER "localhost"#define DEFAULT_EXECUTION_TIME 10#define DEFAULT_CLIENT_TIMEOUT 4000#define DEFAULT_SERVER_TIMEOUT 4000#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGHtypedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;static void PR_CALLBACK Worker(void *arg);typedef struct CSPool_s CSPool_t;typedef struct CSWorker_s CSWorker_t;typedef struct CSServer_s CSServer_t;typedef enum Verbosity{    TEST_LOG_ALWAYS,    TEST_LOG_ERROR,    TEST_LOG_WARNING,    TEST_LOG_NOTICE,    TEST_LOG_INFO,    TEST_LOG_STATUS,    TEST_LOG_VERBOSE} Verbosity;static enum {    thread_nspr, thread_pthread, thread_sproc, thread_win32} thread_provider;static PRInt32 domain = AF_INET;static PRInt32 protocol = 6;  /* TCP */static PRFileDesc *debug_out = NULL;static PRBool debug_mode = PR_FALSE;static PRBool pthread_stats = PR_FALSE;static Verbosity verbosity = TEST_LOG_ALWAYS;static PRThreadScope thread_scope = PR_LOCAL_THREAD;struct CSWorker_s{    PRCList element;        /* list of the server's workers */    PRThread *thread;       /* this worker objects thread */    CSServer_t *server;     /* back pointer to server structure */};struct CSPool_s{    PRCondVar *exiting;    PRCondVar *acceptComplete;    PRUint32 accepting, active, workers;};struct CSServer_s{    PRCList list;           /* head of worker list */    PRLock *ml;    PRThread *thread;       /* the main server thread */    PRCondVar *stateChange;    PRUint16 port;          /* port we're listening on */    PRUint32 backlog;       /* size of our listener backlog */    PRFileDesc *listener;   /* the fd accepting connections */    CSPool_t pool;          /* statistics on worker threads */    CSState_t state;        /* the server's state */    struct                  /* controlling worker counts */    {        PRUint32 minimum, maximum, accepting;    } workers;    /* statistics */    PRIntervalTime started, stopped;    PRUint32 operations, bytesTransferred;};typedef struct CSDescriptor_s{    PRInt32 size;       /* size of transfer */    char filename[60];  /* filename, null padded */} CSDescriptor_t;typedef struct CSClient_s{    PRLock *ml;    PRThread *thread;    PRCondVar *stateChange;    PRNetAddr serverAddress;    CSState_t state;    /* statistics */    PRIntervalTime started, stopped;    PRUint32 operations, bytesTransferred;} CSClient_t;#define TEST_LOG(l, p, a) \    do { \        if (debug_mode || (p <= verbosity)) printf a; \    } while (0)PRLogModuleInfo *cltsrv_log_file = NULL;#define MY_ASSERT(_expr) \    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))#define TEST_ASSERT(_expr) \    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))static void _MY_Assert(const char *s, const char *file, PRIntn ln){    PL_PrintError(NULL);#if DEBUG    PR_Assert(s, file, ln);#endif}  /* _MW_Assert */static PRBool Aborted(PRStatus rv){    return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ?        PR_TRUE : PR_FALSE;}static void TimeOfDayMessage(const char *msg, PRThread* me){    char buffer[100];    PRExplodedTime tod;    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod);    (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);    TEST_LOG(        cltsrv_log_file, TEST_LOG_ALWAYS,        ("%s(0x%p): %s\n", msg, me, buffer));}  /* TimeOfDayMessage */static void PR_CALLBACK Client(void *arg){    PRStatus rv;    PRIntn index;    char buffer[1024];    PRFileDesc *fd = NULL;    PRUintn clipping = DEFAULT_CLIPPING;    CSClient_t *client = (CSClient_t*)arg;    PRThread *me = client->thread = PR_CurrentThread();    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT);    for (index = 0; index < sizeof(buffer); ++index)        buffer[index] = (char)index;    client->started = PR_IntervalNow();    PR_Lock(client->ml);    client->state = cs_run;    PR_NotifyCondVar(client->stateChange);    PR_Unlock(client->ml);    TimeOfDayMessage("Client started at", me);    while (cs_run == client->state)    {        PRInt32 bytes, descbytes, filebytes, netbytes;        (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));        TEST_LOG(cltsrv_log_file, TEST_LOG_INFO,             ("\tClient(0x%p): connecting to server at %s\n", me, buffer));        fd = PR_Socket(domain, SOCK_STREAM, protocol);        TEST_ASSERT(NULL != fd);        rv = PR_Connect(fd, &client->serverAddress, timeout);        if (PR_FAILURE == rv)        {            TEST_LOG(                cltsrv_log_file, TEST_LOG_ERROR,                ("\tClient(0x%p): conection failed\n", me));            goto aborted;        }        memset(descriptor, 0, sizeof(*descriptor));        descriptor->size = PR_htonl(descbytes = rand() % clipping);        PR_snprintf(            descriptor->filename, sizeof(descriptor->filename),            "CS%p%p-%p.dat", client->started, me, client->operations);        TEST_LOG(            cltsrv_log_file, TEST_LOG_VERBOSE,            ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes));        bytes = PR_Send(            fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout);        if (sizeof(CSDescriptor_t) != bytes)        {            if (Aborted(PR_FAILURE)) goto aborted;            if (PR_IO_TIMEOUT_ERROR == PR_GetError())            {                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\tClient(0x%p): send descriptor timeout\n", me));                goto retry;            }        }        TEST_ASSERT(sizeof(*descriptor) == bytes);        netbytes = 0;        while (netbytes < descbytes)        {            filebytes = sizeof(buffer);            if ((descbytes - netbytes) < filebytes)                filebytes = descbytes - netbytes;            TEST_LOG(                cltsrv_log_file, TEST_LOG_VERBOSE,                ("\tClient(0x%p): sending %d bytes\n", me, filebytes));            bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);            if (filebytes != bytes)            {                if (Aborted(PR_FAILURE)) goto aborted;                if (PR_IO_TIMEOUT_ERROR == PR_GetError())                {                    TEST_LOG(                        cltsrv_log_file, TEST_LOG_ERROR,                        ("\tClient(0x%p): send data timeout\n", me));                    goto retry;                }            }            TEST_ASSERT(bytes == filebytes);            netbytes += bytes;        }        filebytes = 0;        while (filebytes < descbytes)        {            netbytes = sizeof(buffer);            if ((descbytes - filebytes) < netbytes)                netbytes = descbytes - filebytes;            TEST_LOG(                cltsrv_log_file, TEST_LOG_VERBOSE,                ("\tClient(0x%p): receiving %d bytes\n", me, netbytes));            bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);            if (-1 == bytes)            {                if (Aborted(PR_FAILURE))                {                    TEST_LOG(                        cltsrv_log_file, TEST_LOG_ERROR,                        ("\tClient(0x%p): receive data aborted\n", me));                    goto aborted;                }                else if (PR_IO_TIMEOUT_ERROR == PR_GetError())                    TEST_LOG(                        cltsrv_log_file, TEST_LOG_ERROR,                        ("\tClient(0x%p): receive data timeout\n", me));				else                    TEST_LOG(                        cltsrv_log_file, TEST_LOG_ERROR,                        ("\tClient(0x%p): receive error (%d, %d)\n",						me, PR_GetError(), PR_GetOSError()));                goto retry;           }            if (0 == bytes)            {                TEST_LOG(                    cltsrv_log_file, TEST_LOG_ERROR,                    ("\t\tClient(0x%p): unexpected end of stream\n",                    PR_CurrentThread()));                break;            }            filebytes += bytes;        }        rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);        if (Aborted(rv)) goto aborted;        TEST_ASSERT(PR_SUCCESS == rv);retry:        (void)PR_Close(fd); fd = NULL;        TEST_LOG(            cltsrv_log_file, TEST_LOG_INFO,            ("\tClient(0x%p): disconnected from server\n", me));        PR_Lock(client->ml);        client->operations += 1;        client->bytesTransferred += 2 * descbytes;        rv = PR_WaitCondVar(client->stateChange, rand() % clipping);        PR_Unlock(client->ml);        if (Aborted(rv)) break;    }aborted:    client->stopped = PR_IntervalNow();    PR_ClearInterrupt();    if (NULL != fd) rv = PR_Close(fd);    PR_Lock(client->ml);    client->state = cs_exit;    PR_NotifyCondVar(client->stateChange);    PR_Unlock(client->ml);    PR_DELETE(descriptor);    TEST_LOG(        cltsrv_log_file, TEST_LOG_ALWAYS,        ("\tClient(0x%p): stopped after %u operations and %u bytes\n",        PR_CurrentThread(), client->operations, client->bytesTransferred));}  /* Client */static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server){    PRStatus drv, rv;    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);

⌨️ 快捷键说明

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