Beispiel #1
0
//static
void
XPCJSRuntime::WatchdogMain(void *arg)
{
    XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg);

    // Lock lasts until we return
    AutoLockJSGC lock(self->mJSRuntime);

    PRIntervalTime sleepInterval;
    while (self->mWatchdogThread)
    {
        // Sleep only 1 second if recently (or currently) active; otherwise, hibernate
        if (self->mLastActiveTime == -1 || PR_Now() - self->mLastActiveTime <= 2*PR_USEC_PER_SEC)
            sleepInterval = PR_TicksPerSecond();
        else
        {
            sleepInterval = PR_INTERVAL_NO_TIMEOUT;
            self->mWatchdogHibernating = PR_TRUE;
        }
#ifdef DEBUG
        PRStatus status =
#endif
            PR_WaitCondVar(self->mWatchdogWakeup, sleepInterval);
        JS_ASSERT(status == PR_SUCCESS);
        JSContext* cx = nsnull;
        while((cx = js_NextActiveContext(self->mJSRuntime, cx)))
        {
            JS_TriggerOperationCallback(cx);
        }
    }

    /* Wake up the main thread waiting for the watchdog to terminate. */
    PR_NotifyCondVar(self->mWatchdogWakeup);
}
Beispiel #2
0
//static
void
XPCJSRuntime::WatchdogMain(void *arg)
{
    XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg);

    // Lock lasts until we return
    AutoLockJSGC lock(self->mJSRuntime);

    while (self->mWatchdogThread)
    {
#ifdef DEBUG
        PRStatus status =
#endif
            PR_WaitCondVar(self->mWatchdogWakeup, PR_TicksPerSecond());
        JS_ASSERT(status == PR_SUCCESS);

        JSContext* cx = nsnull;
        while((cx = js_NextActiveContext(self->mJSRuntime, cx)))
        {
            JS_TriggerOperationCallback(cx);
        }
    }

    /* Wake up the main thread waiting for the watchdog to terminate. */
    PR_NotifyCondVar(self->mWatchdogWakeup);
}
Beispiel #3
0
static PRIntn pt_TimedWait(
    pthread_cond_t *cv, pthread_mutex_t *ml, PRIntervalTime timeout)
{
    int rv;
    struct timeval now;
    struct timespec tmo;
    PRUint32 ticks = PR_TicksPerSecond();

    tmo.tv_sec = (PRInt32)(timeout / ticks);
    tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks));
    tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec);

    /* pthreads wants this in absolute time, off we go ... */
    (void)GETTIMEOFDAY(&now);
    /* that one's usecs, this one's nsecs - grrrr! */
    tmo.tv_sec += now.tv_sec;
    tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
    tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
    tmo.tv_nsec %= PT_BILLION;

    rv = pthread_cond_timedwait(cv, ml, &tmo);

    /* NSPR doesn't report timeouts */
#ifdef _PR_DCETHREADS
    if (rv == -1) return (errno == EAGAIN) ? 0 : errno;
    else return rv;
#else
    return (rv == ETIMEDOUT) ? 0 : rv;
#endif
}  /* pt_TimedWait */
/*
 * FUNCTION: pkix_pl_HttpCertStore_CreateRequestSession
 * DESCRIPTION:
 *
 *  This function takes elements from the HttpCertStoreContext pointed to by
 *  "context" (path, client, and serverSession) and creates a RequestSession.
 *  See the HTTPClient API described in ocspt.h for further details.
 *
 * PARAMETERS:
 *  "context"
 *      The address of the HttpCertStoreContext. Must be non-NULL.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpCertStore Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_pl_HttpCertStore_CreateRequestSession(
        PKIX_PL_HttpCertStoreContext *context,
        void *plContext)
{
        const SEC_HttpClientFcnV1 *hcv1 = NULL;
        SECStatus rv = SECFailure;
        char *pathString = NULL;

        PKIX_ENTER
                (HTTPCERTSTORECONTEXT,
                "pkix_pl_HttpCertStore_CreateRequestSession");
        PKIX_NULLCHECK_TWO(context, context->serverSession);

        pathString = PR_smprintf("%s", context->path);

        if (context->client->version == 1) {
                hcv1 = &(context->client->fcnTable.ftable1);

                if (context->requestSession != NULL) {
                        PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, hcv1->freeFcn,
                                (context->requestSession));
                        context->requestSession = 0;
                }

                PKIX_PL_NSSCALLRV
                        (HTTPCERTSTORECONTEXT, rv, hcv1->createFcn,
                        (context->serverSession,
                        "http",
                        pathString,
                        "GET",
                        PR_TicksPerSecond() * 60,
                        &(context->requestSession)));

                if (rv != SECSuccess) {
                        if (pathString != NULL) {
                                PORT_Free(pathString);
                        }
                        PKIX_ERROR(PKIX_HTTPSERVERERROR);
                }
        } else {
                PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
        }

cleanup:

        PKIX_RETURN(HTTPCERTSTORECONTEXT);

}
_pt_wait(PRThread *thread, PRIntervalTime timeout)
{
int rv;
struct timeval now;
struct timespec tmo;
PRUint32 ticks = PR_TicksPerSecond();


	if (timeout != PR_INTERVAL_NO_TIMEOUT) {
		tmo.tv_sec = timeout / ticks;
		tmo.tv_nsec = timeout - (tmo.tv_sec * ticks);
		tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO *
											tmo.tv_nsec);

		/* pthreads wants this in absolute time, off we go ... */
		(void)GETTIMEOFDAY(&now);
		/* that one's usecs, this one's nsecs - grrrr! */
		tmo.tv_sec += now.tv_sec;
		tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
		tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
		tmo.tv_nsec %= PT_BILLION;
	}

	pthread_mutex_lock(&thread->md.pthread_mutex);
	thread->md.wait--;
	if (thread->md.wait < 0) {
		if (timeout != PR_INTERVAL_NO_TIMEOUT) {
			rv = pthread_cond_timedwait(&thread->md.pthread_cond,
					&thread->md.pthread_mutex, &tmo);
        }
		else
			rv = pthread_cond_wait(&thread->md.pthread_cond,
					&thread->md.pthread_mutex);
		if (rv != 0) {
			thread->md.wait++;
		}
	} else
		rv = 0;
	pthread_mutex_unlock(&thread->md.pthread_mutex);

	return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
}
int main(int argc, const char **argv) {	
	
	if (argc != 3) usage(argv[0]);
	
	try {
	  WikiDumpParser parser(argv[1], argv[2]);
	  PRThread *runner = 0;
	  {
	    MonitorBlock sync(&parser);
	    runner = PR_CreateThread(PR_USER_THREAD, myThreadStart, &parser, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);

	    sync.wait();
	  }
	  size_t ticksPerSecond = PR_TicksPerSecond();

	  float progress;

	  do {
	    progress = parser.getProgress();
	    std::cout << progress << std::endl;
	    PR_Sleep(1 * ticksPerSecond);
	  } while (progress > 0 && progress < 1);

	  PR_JoinThread(runner);

	  if (progress == -1) {
	    std::cerr << parser.errMsg() << std::endl;

	    return 1;
	  }
	  
	  //parser.parse();
	
	} catch (std::exception &e) {
		std::cerr << "error: " << e.what() << std::endl;
	} catch (...) {
		std::cerr << "error: ..." << std::endl;
	}		

	return 0;
}
 void NotifyExpired(Object* aObj) {
   LogAction(aObj, "Expired");
   PRIntervalTime now = PR_IntervalNow();
   uint32_t timeDiffMS = (now - aObj->mLastUsed)*1000/PR_TicksPerSecond();
   // See the comment for NotifyExpired in nsExpirationTracker.h for these
   // bounds
   uint32_t lowerBoundMS = (K-1)*periodMS - slackMS;
   uint32_t upperBoundMS = K*(periodMS + sleepPeriodMS) + slackMS;
   if (logging) {
     printf("Checking: %d-%d = %d [%d,%d]\n",
            now, aObj->mLastUsed, timeDiffMS, lowerBoundMS, upperBoundMS);
   }
   if (timeDiffMS < lowerBoundMS || timeDiffMS > upperBoundMS) {
     EXPECT_TRUE(timeDiffMS < periodMS && aObj->mExpired);
   }
   aObj->Touch();
   aObj->mExpired = true;
   DoRandomOperation();
   DoRandomOperation();
   DoRandomOperation();
 }
Beispiel #8
0
SECStatus nsNSSHttpRequestSession::createFcn(SEC_HTTP_SERVER_SESSION session,
                                             const char *http_protocol_variant,
                                             const char *path_and_query_string,
                                             const char *http_request_method, 
                                             const PRIntervalTime timeout, 
                                             SEC_HTTP_REQUEST_SESSION *pRequest)
{
  if (!session || !http_protocol_variant || !path_and_query_string || 
      !http_request_method || !pRequest)
    return SECFailure;

  nsNSSHttpServerSession* hss = static_cast<nsNSSHttpServerSession*>(session);
  if (!hss)
    return SECFailure;

  nsNSSHttpRequestSession *rs = new nsNSSHttpRequestSession;
  if (!rs)
    return SECFailure;

  rs->mTimeoutInterval = timeout;

  // Use a maximum timeout value of 10 seconds because of bug 404059.
  // FIXME: Use a better approach once 406120 is ready.
  PRUint32 maxBug404059Timeout = PR_TicksPerSecond() * 10;
  if (timeout > maxBug404059Timeout) {
    rs->mTimeoutInterval = maxBug404059Timeout;
  }

  rs->mURL.Append(nsDependentCString(http_protocol_variant));
  rs->mURL.AppendLiteral("://");
  rs->mURL.Append(hss->mHost);
  rs->mURL.AppendLiteral(":");
  rs->mURL.AppendInt(hss->mPort);
  rs->mURL.Append(path_and_query_string);

  rs->mRequestMethod = nsDependentCString(http_request_method);

  *pRequest = (void*)rs;
  return SECSuccess;
}
Beispiel #9
0
nsresult
TimeStamp::Startup()
{
  if (gInitialized)
    return NS_OK;

  const char *envp;
  APIRET rc;

  // Use the same variable as NSPR's os2inrval.c does to let the user disable the
  // high-resolution timer (it is known that it doesn't work well on some hardware)
  if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) {
    if (atoi(envp) != 1) {
      // Attempt to use the high-res timer
      rc = DosTmrQueryFreq(&gTicksPerSec);
      if (rc == NO_ERROR)
        gUseHighResTimer = true;
    }
  }

  if (!gUseHighResTimer) {
    // TimeStamp has to use bare PRLock instead of mozilla::Mutex
    // because TimeStamp can be used very early in startup.
    gTimeStampLock = PR_NewLock();
    if (!gTimeStampLock)
      return NS_ERROR_OUT_OF_MEMORY;
    gRolloverCount = 1;
    gLastNow = 0;
    gTicksPerSec = PR_TicksPerSecond();
  }

  gTicksPerSecDbl = gTicksPerSec;
  gTicksPerMsDbl = gTicksPerSecDbl / 1000.0;

  gInitialized = true;
  sFirstTimeStamp = TimeStamp::Now();
  sProcessCreation = TimeStamp();

  return NS_OK;
}
Beispiel #10
0
void
VideoSourceCanvas::Grabber(void *data)
{
    nsresult rv;
    PRUint32 wr;
    VideoSourceCanvas *vs = static_cast<VideoSourceCanvas*>(data);
    
    int isize = vs->GetFrameSize();
    int fsize = vs->width * vs->height * 4;
    char *i420 = (char *)PR_Calloc(isize, 1);
    PRUint8 *rgb32 = (PRUint8 *)PR_Calloc(fsize, 1);

    PRTime epoch_c;
    PRFloat64 epoch;
    PRIntervalTime ticks = PR_TicksPerSecond() / 30;
    while (vs->running) {
        PR_Sleep(ticks);
        if (vs->is_rec == PR_FALSE) continue;
        
        rv = vs->vCanvas->GetImageData_explicit(
            0, 0, vs->width, vs->height, rgb32, fsize
        );
        if (NS_FAILED(rv)) continue;

        RGB32toI420(vs->width, vs->height, (const char *)rgb32, i420);
        
        epoch_c = PR_Now();
        epoch = (PRFloat64)(epoch_c / MICROSECONDS);
        epoch += ((PRFloat64)(epoch_c % MICROSECONDS)) / MICROSECONDS;
        rv = vs->output->Write((const char *)&epoch, sizeof(PRFloat64), &wr);
        rv = vs->output->Write((const char *)&isize, sizeof(PRUint32), &wr);
        rv = vs->output->Write((const char *)i420, isize, &wr);
    }

    PR_Free(i420);
    PR_Free(rgb32);
    return;
}
static void TestConversions(void)
{
    PRIntervalTime ticks = PR_TicksPerSecond();

	if (debug_mode) {
    PR_fprintf(output, "PR_TicksPerSecond: %ld\n\n", ticks);
    PR_fprintf(output, "PR_SecondsToInterval(1): %ld\n", PR_SecondsToInterval(1));
    PR_fprintf(output, "PR_MillisecondsToInterval(1000): %ld\n", PR_MillisecondsToInterval(1000));
    PR_fprintf(output, "PR_MicrosecondsToInterval(1000000): %ld\n\n", PR_MicrosecondsToInterval(1000000));

    PR_fprintf(output, "PR_SecondsToInterval(3): %ld\n", PR_SecondsToInterval(3));
    PR_fprintf(output, "PR_MillisecondsToInterval(3000): %ld\n", PR_MillisecondsToInterval(3000));
    PR_fprintf(output, "PR_MicrosecondsToInterval(3000000): %ld\n\n", PR_MicrosecondsToInterval(3000000));

    PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks));
    PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks));
    PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks));

    ticks *= 3;
    PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks));
    PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks));
    PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks));
	} /*end debug mode */
}  /* TestConversions */
Beispiel #12
0
TimeDuration
TimeDuration::FromMilliseconds(double aMilliseconds)
{
  static double kTicksPerMs = double(PR_TicksPerSecond()) / 1000.0;
  return TimeDuration::FromTicks(aMilliseconds * kTicksPerMs);
}
Beispiel #13
0
double
TimeDuration::ToSeconds() const
{
 return double(mValue)/PR_TicksPerSecond();
}
Beispiel #14
0
PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
{
#ifdef BSD_SELECT
    fd_set rd, wt, ex;
#else
    int rd, wt, ex;
    int* socks;
    unsigned long msecs;
    int i, j;
#endif
    PRFileDesc *bottom;
    PRPollDesc *pd, *epd;
    PRInt32 maxfd = -1, ready, err;
    PRIntervalTime remaining, elapsed, start;

#ifdef BSD_SELECT
    struct timeval tv, *tvp = NULL;

    FD_ZERO(&rd);
    FD_ZERO(&wt);
    FD_ZERO(&ex);
#else
    rd = 0;
    wt = 0;
    ex = 0;
    socks = (int) PR_MALLOC( npds * 3 * sizeof(int) );
    
    if (!socks)
    {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        return -1;
    }
#endif

    ready = 0;
    for (pd = pds, epd = pd + npds; pd < epd; pd++)
    {
        PRInt16 in_flags_read = 0, in_flags_write = 0;
        PRInt16 out_flags_read = 0, out_flags_write = 0;

        if ((NULL != pd->fd) && (0 != pd->in_flags))
        {
            if (pd->in_flags & PR_POLL_READ)
            {
                in_flags_read = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
            }
            if (pd->in_flags & PR_POLL_WRITE)
            {
                in_flags_write = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
            }
            if ((0 != (in_flags_read & out_flags_read)) ||
                (0 != (in_flags_write & out_flags_write)))
            {
                /* this one's ready right now */
                if (0 == ready)
                {
                    /*
                     * We will have to return without calling the
                     * system poll/select function.  So zero the
                     * out_flags fields of all the poll descriptors
                     * before this one.
                     */
                    PRPollDesc *prev;
                    for (prev = pds; prev < pd; prev++)
                    {
                        prev->out_flags = 0;
                    }
                }
                ready += 1;
                pd->out_flags = out_flags_read | out_flags_write;
            }
            else
            {
                pd->out_flags = 0;  /* pre-condition */

                /* make sure this is an NSPR supported stack */
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);  /* what to do about that? */
                if ((NULL != bottom) &&
                    (_PR_FILEDESC_OPEN == bottom->secret->state))
                {
                    if (0 == ready)
                    {
                        PRInt32 osfd = bottom->secret->md.osfd;
                        if (osfd > maxfd) 
                            maxfd = osfd;
                        if (in_flags_read & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
#ifdef BSD_SELECT
                            FD_SET(osfd, &rd);
#else
                            socks[rd] = osfd;
                            rd++;              
#endif
                        }
                        if (in_flags_read & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
#ifdef BSD_SELECT
                            FD_SET(osfd, &wt);
#else
                            socks[npds+wt] = osfd;
                            wt++;              
#endif
                        }
                        if (in_flags_write & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
#ifdef BSD_SELECT
                            FD_SET(osfd, &rd);
#else
                            socks[rd] = osfd;
                            rd++;              
#endif
                        }
                        if (in_flags_write & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
#ifdef BSD_SELECT
                            FD_SET(osfd, &wt);
#else
                            socks[npds+wt] = osfd;
                            wt++;              
#endif
                        }
                        if (pd->in_flags & PR_POLL_EXCEPT)
                        {
#ifdef BSD_SELECT
                            FD_SET(osfd, &ex);
#else
                            socks[npds*2+ex] = osfd;
                            ex++;
#endif
                        }
                    }
                }
                else
                {
                    if (0 == ready)
                    {
                        PRPollDesc *prev;
                        for (prev = pds; prev < pd; prev++)
                        {
                            prev->out_flags = 0;
                        }
                    }
                    ready += 1;  /* this will cause an abrupt return */
                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
                }
            }
        }
        else
        {
            pd->out_flags = 0;
        }
    }

    if (0 != ready)
    {
#ifndef BSD_SELECT
        PR_Free(socks);
#endif
        return ready;  /* no need to block */
    }

    remaining = timeout;
    start = PR_IntervalNow();

retry:
#ifdef BSD_SELECT
    if (timeout != PR_INTERVAL_NO_TIMEOUT)
    {
        PRInt32 ticksPerSecond = PR_TicksPerSecond();
        tv.tv_sec = remaining / ticksPerSecond;
        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
        tvp = &tv;
    }

    ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp);
#else
    switch (timeout)
    {
        case PR_INTERVAL_NO_WAIT:
            msecs = 0;
            break;
        case PR_INTERVAL_NO_TIMEOUT:
            msecs = -1;
            break;
        default:
            msecs = PR_IntervalToMilliseconds(remaining);
    }

     /* compact array */
    for( i = rd, j = npds; j < npds+wt; i++,j++ )
        socks[i] = socks[j];
    for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ )
        socks[i] = socks[j];
    
    ready = os2_select(socks, rd, wt, ex, msecs);
#endif

    if (ready == -1 && errno == EINTR)
    {
        if (timeout == PR_INTERVAL_NO_TIMEOUT)
            goto retry;
        else
        {
            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
            if (elapsed > timeout)
                ready = 0;  /* timed out */
            else
            {
                remaining = timeout - elapsed;
                goto retry;
            }
        }
    }

    /*
    ** Now to unravel the select sets back into the client's poll
    ** descriptor list. Is this possibly an area for pissing away
    ** a few cycles or what?
    */
    if (ready > 0)
    {
        ready = 0;
        for (pd = pds, epd = pd + npds; pd < epd; pd++)
        {
            PRInt16 out_flags = 0;
            if ((NULL != pd->fd) && (0 != pd->in_flags))
            {
                PRInt32 osfd;
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);

                osfd = bottom->secret->md.osfd;

#ifdef BSD_SELECT
                if (FD_ISSET(osfd, &rd))
#else
                if( IsSocketSet(osfd, socks, 0, rd) )        
#endif
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
                        out_flags |= PR_POLL_WRITE;
                } 

#ifdef BSD_SELECT
                if (FD_ISSET(osfd, &wt))
#else
                if( IsSocketSet(osfd, socks, rd, wt) )        
#endif
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
                        out_flags |= PR_POLL_WRITE;
                } 

#ifdef BSD_SELECT
                if (FD_ISSET(osfd, &ex))
#else
                if( IsSocketSet(osfd, socks, rd+wt, ex) )        
#endif
                {
                    out_flags |= PR_POLL_EXCEPT;
                }
            }
            pd->out_flags = out_flags;
            if (out_flags) ready++;
        }
        PR_ASSERT(ready > 0);
    }
    else if (ready < 0)
    {
        err = _MD_ERRNO();
        if (err == EBADF)
        {
            /* Find the bad fds */
            int optval;
            int optlen = sizeof(optval);
            ready = 0;
            for (pd = pds, epd = pd + npds; pd < epd; pd++)
            {
                pd->out_flags = 0;
                if ((NULL != pd->fd) && (0 != pd->in_flags))
                {
                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                    if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
                        SO_TYPE, (char *) &optval, &optlen) == -1)
                    {
                        PR_ASSERT(sock_errno() == ENOTSOCK);
                        if (sock_errno() == ENOTSOCK)
                        {
                            pd->out_flags = PR_POLL_NVAL;
                            ready++;
                        }
                    }
                }
            }
            PR_ASSERT(ready > 0);
        }
        else
            _PR_MD_MAP_SELECT_ERROR(err);
    }

#ifndef BSD_SELECT
    PR_Free(socks);
#endif
    return ready;
}
Beispiel #15
0
static PRInt32 NativeThreadSelect(
    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
{
    /*
     * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
     */
    fd_set rd, wt, ex;
    PRFileDesc *bottom;
    PRPollDesc *pd, *epd;
    PRInt32 maxfd = -1, ready, err;
    PRIntervalTime remaining, elapsed, start;

    struct timeval tv, *tvp = NULL;

    FD_ZERO(&rd);
    FD_ZERO(&wt);
    FD_ZERO(&ex);

    ready = 0;
    for (pd = pds, epd = pd + npds; pd < epd; pd++)
    {
        PRInt16 in_flags_read = 0, in_flags_write = 0;
        PRInt16 out_flags_read = 0, out_flags_write = 0;

        if ((NULL != pd->fd) && (0 != pd->in_flags))
        {
            if (pd->in_flags & PR_POLL_READ)
            {
                in_flags_read = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
            }
            if (pd->in_flags & PR_POLL_WRITE)
            {
                in_flags_write = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
            }
            if ((0 != (in_flags_read & out_flags_read))
            || (0 != (in_flags_write & out_flags_write)))
            {
                /* this one's ready right now */
                if (0 == ready)
                {
                    /*
                     * We will have to return without calling the
                     * system poll/select function.  So zero the
                     * out_flags fields of all the poll descriptors
                     * before this one.
                     */
                    PRPollDesc *prev;
                    for (prev = pds; prev < pd; prev++)
                    {
                        prev->out_flags = 0;
                    }
                }
                ready += 1;
                pd->out_flags = out_flags_read | out_flags_write;
            }
            else
            {
                pd->out_flags = 0;  /* pre-condition */

                /* make sure this is an NSPR supported stack */
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);  /* what to do about that? */
                if ((NULL != bottom)
                && (_PR_FILEDESC_OPEN == bottom->secret->state))
                {
                    if (0 == ready)
                    {
                        PRInt32 osfd = bottom->secret->md.osfd;
                        if (osfd > maxfd) maxfd = osfd;
                        if (in_flags_read & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
                            FD_SET(osfd, &rd);
                        }
                        if (in_flags_read & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
                            FD_SET(osfd, &wt);
                        }
                        if (in_flags_write & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
                            FD_SET(osfd, &rd);
                        }
                        if (in_flags_write & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
                            FD_SET(osfd, &wt);
                        }
                        if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
                    }
                }
                else
                {
                    if (0 == ready)
                    {
                        PRPollDesc *prev;
                        for (prev = pds; prev < pd; prev++)
                        {
                            prev->out_flags = 0;
                        }
                    }
                    ready += 1;  /* this will cause an abrupt return */
                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
                }
            }
        }
        else
        {
            pd->out_flags = 0;
        }
    }

    if (0 != ready) return ready;  /* no need to block */

    remaining = timeout;
    start = PR_IntervalNow();

retry:
    if (timeout != PR_INTERVAL_NO_TIMEOUT)
    {
        PRInt32 ticksPerSecond = PR_TicksPerSecond();
        tv.tv_sec = remaining / ticksPerSecond;
        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
        tvp = &tv;
    }

    ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);

    if (ready == -1 && errno == EINTR)
    {
        if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
        else
        {
            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
            if (elapsed > timeout) ready = 0;  /* timed out */
            else
            {
                remaining = timeout - elapsed;
                goto retry;
            }
        }
    }

    /*
    ** Now to unravel the select sets back into the client's poll
    ** descriptor list. Is this possibly an area for pissing away
    ** a few cycles or what?
    */
    if (ready > 0)
    {
        ready = 0;
        for (pd = pds, epd = pd + npds; pd < epd; pd++)
        {
            PRInt16 out_flags = 0;
            if ((NULL != pd->fd) && (0 != pd->in_flags))
            {
                PRInt32 osfd;
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);

                osfd = bottom->secret->md.osfd;

                if (FD_ISSET(osfd, &rd))
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
                        out_flags |= PR_POLL_WRITE;
                } 
                if (FD_ISSET(osfd, &wt))
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
                        out_flags |= PR_POLL_WRITE;
                } 
                if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
            }
            pd->out_flags = out_flags;
            if (out_flags) ready++;
        }
        PR_ASSERT(ready > 0);
    }
    else if (ready < 0)
    {
        err = _MD_ERRNO();
        if (err == EBADF)
        {
            /* Find the bad fds */
            ready = 0;
            for (pd = pds, epd = pd + npds; pd < epd; pd++)
            {
                pd->out_flags = 0;
                if ((NULL != pd->fd) && (0 != pd->in_flags))
                {
                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                    if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
                    {
                        pd->out_flags = PR_POLL_NVAL;
                        ready++;
                    }
                }
            }
            PR_ASSERT(ready > 0);
        }
        else _PR_MD_MAP_SELECT_ERROR(err);
    }

    return ready;
}  /* NativeThreadSelect */
PRFloat64 StatsManagerUtil::getResponseTime(StatsProfileBucket& profile)
{
    return ((PRFloat64) (PRInt64) (profile.ticksDispatch +
                                   profile.ticksFunction)) /
                        ((PRInt64) profile.countRequests * PR_TicksPerSecond());
}
int
main(int32_t argc, char *argv[])
{
    if (test_common_init(&argc, &argv) != 0)
        return -1;

    bool allTestsPassed = true;

    ScopedXPCOM xpcom;
    if (NS_FAILED(xpcom.rv))
      return -1;

    {
      nsresult rv0;

      nsCOMPtr<nsICookieService> cookieService =
        do_GetService(kCookieServiceCID, &rv0);
      if (NS_FAILED(rv0)) return -1;

      nsCOMPtr<nsIPrefBranch> prefBranch =
        do_GetService(kPrefServiceCID, &rv0);
      if (NS_FAILED(rv0)) return -1;

      InitPrefs(prefBranch);

      bool rv[20];
      nsCString cookie;

      /* The basic idea behind these tests is the following:
       *
       * we set() some cookie, then try to get() it in various ways. we have
       * several possible tests we perform on the cookie string returned from
       * get():
       *
       * a) check whether the returned string is null (i.e. we got no cookies
       *    back). this is used e.g. to ensure a given cookie was deleted
       *    correctly, or to ensure a certain cookie wasn't returned to a given
       *    host.
       * b) check whether the returned string exactly matches a given string.
       *    this is used where we want to make sure our cookie service adheres to
       *    some strict spec (e.g. ordering of multiple cookies), or where we
       *    just know exactly what the returned string should be.
       * c) check whether the returned string contains/does not contain a given
       *    string. this is used where we don't know/don't care about the
       *    ordering of multiple cookies - we just want to make sure the cookie
       *    string contains them all, in some order.
       *
       * the results of each individual testing operation from CheckResult() is
       * stored in an array of bools, which is then checked against the expected
       * outcomes (all successes), by PrintResult(). the overall result of all
       * tests to date is kept in |allTestsPassed|, for convenient display at the
       * end.
       *
       * Interpreting the output:
       * each setting/getting operation will print output saying exactly what
       * it's doing and the outcome, respectively. this information is only
       * useful for debugging purposes; the actual result of the tests is
       * printed at the end of each block of tests. this will either be "all
       * tests passed" or "tests X Y Z failed", where X, Y, Z are the indexes
       * of rv (i.e. zero-based). at the conclusion of all tests, the overall
       * passed/failed result is printed.
       *
       * NOTE: this testsuite is not yet comprehensive or complete, and is
       * somewhat contrived - still under development, and needs improving!
       */

      // *** basic tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning basic tests...\n");

      // test some basic variations of the domain & path
      SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic", nullptr);
      GetACookie(cookieService, "http://www.basic.com", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic");
      GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt", nullptr, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic");
      GetACookie(cookieService, "http://www.basic.com./", nullptr, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.basic.com.", nullptr, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt", nullptr, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.basic2.com/", nullptr, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic; max-age=-1", nullptr);
      GetACookie(cookieService, "http://www.basic.com/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 7) && allTestsPassed;


      // *** domain tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning domain tests...\n");

      // test some variations of the domain & path, for different domains of
      // a domain cookie
      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com", nullptr);
      GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://domain.com.", nullptr, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com; max-age=-1", nullptr);
      GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com", nullptr);
      GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://bah.domain.com", nullptr, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com; max-age=-1", nullptr);
      GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.foo.domain.com", nullptr);
      GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=moose.com", nullptr);
      GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
      rv[10] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com.", nullptr);
      GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
      rv[11] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com", nullptr);
      GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
      rv[12] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com.", nullptr);
      GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
      rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; path=\"/bogus\"", nullptr);
      GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie));
      rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=taco");
      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; max-age=-1", nullptr);
      GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie));
      rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 16) && allTestsPassed;


      // *** path tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path tests...\n");

      // test some variations of the domain & path, for different paths of
      // a path cookie
      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path", nullptr);
      GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path/hithere.foo", nullptr, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path?hithere/foo", nullptr, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path2", nullptr, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://path.net/path2/", nullptr, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path; max-age=-1", nullptr);
      GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/", nullptr);
      GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/; max-age=-1", nullptr);
      GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);

      // note that a site can set a cookie for a path it's not on.
      // this is an intentional deviation from spec (see comments in
      // nsCookieService::CheckPath()), so we test this functionality too
      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/", nullptr);
      GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie));
      rv[10] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://path.net/foo", nullptr, getter_Copies(cookie));
      rv[11] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/; max-age=-1", nullptr);
      GetACookie(cookieService, "http://path.net/foo/", nullptr, getter_Copies(cookie));
      rv[12] = CheckResult(cookie.get(), MUST_BE_NULL);

      // bug 373228: make sure cookies with paths longer than 1024 bytes,
      // and cookies with paths or names containing tabs, are rejected.
      // the following cookie has a path > 1024 bytes explicitly specified in the cookie
      SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr);
      GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", nullptr, getter_Copies(cookie));
      rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie has a path > 1024 bytes implicitly specified by the uri path
      SetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, "test=path", nullptr);
      GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, getter_Copies(cookie));
      rv[14] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie includes a tab in the path
      SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/foo\tbar/", nullptr);
      GetACookie(cookieService, "http://path.net/foo\tbar/", nullptr, getter_Copies(cookie));
      rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie includes a tab in the name
      SetACookie(cookieService, "http://path.net/", nullptr, "test\ttabs=tab", nullptr);
      GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie));
      rv[16] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie includes a tab in the value - allowed
      SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest", nullptr);
      GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie));
      rv[17] = CheckResult(cookie.get(), MUST_EQUAL, "test=tab\ttest");
      SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest; max-age=-1", nullptr);
      GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie));
      rv[18] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 19) && allTestsPassed;


      // *** expiry & deletion tests
      // XXX add server time str parsing tests here
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning expiry & deletion tests...\n");

      // test some variations of the expiry time,
      // and test deletion of previously set cookies
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-1", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=0", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=bad", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT\"", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-20", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr);
      SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=expiry; max-age=60", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[10] = CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry");
      rv[11] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry");
      SetACookie(cookieService, "http://expireme.org/", nullptr, "test=differentvalue; max-age=0", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[12] = CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry");
      SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=evendifferentvalue; max-age=0", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://foo.expireme.org/", nullptr, "test=expiry; domain=.expireme.org; max-age=60", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://bar.expireme.org/", nullptr, "test=differentvalue; domain=.expireme.org; max-age=0", nullptr);
      GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
      rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 16) && allTestsPassed;


      // *** multiple cookie tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning multiple cookie tests...\n");

      // test the setting of multiple cookies, and test the order of precedence
      // (a later cookie overwriting an earlier one, in the same header string)
      SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=multiple; domain=.multiple.cookies \n test=different \n test=same; domain=.multiple.cookies \n newtest=ciao \n newtest=foo; max-age=-6 \n newtest=reincarnated", nullptr);
      GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple");
      rv[1] = CheckResult(cookie.get(), MUST_CONTAIN, "test=different");
      rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=same");
      rv[3] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao");
      rv[4] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo");
      rv[5] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated");
      SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=expiry; domain=.multiple.cookies; max-age=0", nullptr);
      GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same");
      SetACookie(cookieService, "http://multiple.cookies/", nullptr,  "\n test=different; max-age=0 \n", nullptr);
      GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different");
      SetACookie(cookieService, "http://multiple.cookies/", nullptr,  "newtest=dead; max-age=0", nullptr);
      GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 9) && allTestsPassed;


      // *** parser tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning parser tests...\n");

      // test the cookie header parser, under various circumstances.
      SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=parser");
      SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; max-age=0", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://parser.test/", nullptr, "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; max-age=6\nfive; max-age=2.63,", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=\"fubar! = foo");
      rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "five");
      SetACookie(cookieService, "http://parser.test/", nullptr, "test=kill; domain=.parser.test; max-age=0 \n five; max-age=0", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);

      // test the handling of VALUE-only cookies (see bug 169091),
      // i.e. "six" should assume an empty NAME, which allows other VALUE-only
      // cookies to overwrite it
      SetACookie(cookieService, "http://parser.test/", nullptr, "six", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "six");
      SetACookie(cookieService, "http://parser.test/", nullptr, "seven", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "seven");
      SetACookie(cookieService, "http://parser.test/", nullptr, " =eight", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "eight");
      SetACookie(cookieService, "http://parser.test/", nullptr, "test=six", nullptr);
      GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_CONTAIN, "test=six");

      allTestsPassed = PrintResult(rv, 10) && allTestsPassed;


      // *** path ordering tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path ordering tests...\n");

      // test that cookies are returned in path order - longest to shortest.
      // if the header doesn't specify a path, it's taken from the host URI.
      SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test1=path; path=/one/two/three", nullptr);
      SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test2=path; path=/one \n test3=path; path=/one/two/three/four \n test4=path; path=/one/two \n test5=path; path=/one/two/", nullptr);
      SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/", nullptr, "test6=path", nullptr);
      SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, "test7=path; path=", nullptr);
      SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test8=path; path=/", nullptr);
      GetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test7=path; test6=path; test3=path; test1=path; test5=path; test4=path; test2=path; test8=path");

      allTestsPassed = PrintResult(rv, 1) && allTestsPassed;


      // *** httponly tests 
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning httponly tests...\n");

      // Since this cookie is NOT set via http, setting it fails
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly");
      GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Since this cookie is set via http, it can be retrieved
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
      GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
      // ... but not by web content
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Non-Http cookies should not replace HttpOnly cookies
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=not-httponly");
      GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
      // ... and, if an HttpOnly cookie already exists, should not be set at all
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Non-Http cookies should not delete HttpOnly cookies
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; max-age=-1");
      GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
      // ... but HttpOnly cookies should
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly; max-age=-1", nullptr);
      GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Non-Httponly cookies can replace HttpOnly cookies when set over http
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr);
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly");
      // scripts should not be able to set httponly cookies by replacing an existing non-httponly cookie
      SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr);
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly");
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly");

      allTestsPassed = PrintResult(rv, 9) && allTestsPassed;


      // *** nsICookieManager{2} interface tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n");
      nsCOMPtr<nsICookieManager> cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0);
      if (NS_FAILED(rv0)) return -1;
      nsCOMPtr<nsICookieManager2> cookieMgr2 = do_QueryInterface(cookieMgr);
      if (!cookieMgr2) return -1;
      
      // first, ensure a clean slate
      rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll());
      // add some cookies
      rv[1] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
                                           NS_LITERAL_CSTRING("/foo"),           // path
                                           NS_LITERAL_CSTRING("test1"),          // name
                                           NS_LITERAL_CSTRING("yes"),            // value
                                           false,                             // is secure
                                           false,                             // is httponly
                                           true,                              // is session
                                           INT64_MAX));                          // expiry time
      rv[2] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
                                           NS_LITERAL_CSTRING("/foo"),           // path
                                           NS_LITERAL_CSTRING("test2"),          // name
                                           NS_LITERAL_CSTRING("yes"),            // value
                                           false,                             // is secure
                                           true,                              // is httponly
                                           true,                              // is session
                                           PR_Now() / PR_USEC_PER_SEC + 2));     // expiry time
      rv[3] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"),     // domain
                                           NS_LITERAL_CSTRING("/rabbit"),        // path
                                           NS_LITERAL_CSTRING("test3"),          // name
                                           NS_LITERAL_CSTRING("yes"),            // value
                                           false,                             // is secure
                                           false,                             // is httponly
                                           true,                              // is session
                                           INT64_MAX));                          // expiry time
      // confirm using enumerator
      nsCOMPtr<nsISimpleEnumerator> enumerator;
      rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator)));
      int32_t i = 0;
      bool more;
      nsCOMPtr<nsICookie2> expiredCookie, newDomainCookie;
      while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
        nsCOMPtr<nsISupports> cookie;
        if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break;
        ++i;
        
        // keep tabs on the second and third cookies, so we can check them later
        nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie));
        if (!cookie2) break;
        nsAutoCString name;
        cookie2->GetName(name);
        if (name == NS_LITERAL_CSTRING("test2"))
          expiredCookie = cookie2;
        else if (name == NS_LITERAL_CSTRING("test3"))
          newDomainCookie = cookie2;
      }
      rv[5] = i == 3;
      // check the httpOnly attribute of the second cookie is honored
      GetACookie(cookieService, "http://cookiemgr.test/foo/", nullptr, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes");
      GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes");
      // check CountCookiesFromHost()
      uint32_t hostCookies = 0;
      rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
              hostCookies == 2;
      // check CookieExists() using the third cookie
      bool found;
      rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && found;
      // remove the cookie, block it, and ensure it can't be added again
      rv[10] = NS_SUCCEEDED(cookieMgr->Remove(NS_LITERAL_CSTRING("new.domain"), // domain
                                              NS_LITERAL_CSTRING("test3"),      // name
                                              NS_LITERAL_CSTRING("/rabbit"),    // path
                                              true));                        // is blocked
      rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found;
      rv[12] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"),     // domain
                                            NS_LITERAL_CSTRING("/rabbit"),        // path
                                            NS_LITERAL_CSTRING("test3"),          // name
                                            NS_LITERAL_CSTRING("yes"),            // value
                                            false,                             // is secure
                                            false,                             // is httponly
                                            true,                              // is session
                                            INT64_MIN));                          // expiry time
      rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found;
      // sleep four seconds, to make sure the second cookie has expired
      PR_Sleep(4 * PR_TicksPerSecond());
      // check that both CountCookiesFromHost() and CookieExists() count the
      // expired cookie
      rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
              hostCookies == 2;
      rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExists(expiredCookie, &found)) && found;
      // double-check RemoveAll() using the enumerator
      rv[16] = NS_SUCCEEDED(cookieMgr->RemoveAll());
      rv[17] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))) &&
               NS_SUCCEEDED(enumerator->HasMoreElements(&more)) &&
               !more;

      allTestsPassed = PrintResult(rv, 18) && allTestsPassed;


      // *** eviction and creation ordering tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation ordering tests...\n");

      // test that cookies are
      // a) returned by order of creation time (oldest first, newest last)
      // b) evicted by order of lastAccessed time, if the limit on cookies per host (50) is reached
      nsAutoCString name;
      nsAutoCString expected;
      for (int32_t i = 0; i < 60; ++i) {
        name = NS_LITERAL_CSTRING("test");
        name.AppendInt(i);
        name += NS_LITERAL_CSTRING("=creation");
        SetACookie(cookieService, "http://creation.ordering.tests/", nullptr, name.get(), nullptr);

        if (i >= 10) {
          expected += name;
          if (i < 59)
            expected += NS_LITERAL_CSTRING("; ");
        }
      }
      GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get());

      allTestsPassed = PrintResult(rv, 1) && allTestsPassed;


      // XXX the following are placeholders: add these tests please!
      // *** "noncompliant cookie" tests
      // *** IP address tests
      // *** speed tests


      sBuffer = PR_sprintf_append(sBuffer, "\n*** Result: %s!\n\n", allTestsPassed ? "all tests passed" : "TEST(S) FAILED");
    }

    if (!allTestsPassed) {
      // print the entire log
      printf("%s", sBuffer);
      return 1;
    }

    PR_smprintf_free(sBuffer);
    sBuffer = nullptr;

    return 0;
}
Beispiel #18
0
/*
 * Destroy a Repl_Objset.
 * Arguments:
 *  o: the object set to be destroyed
 *  maxwait: the maximum time to wait for all object refcnts to 
 *           go to zero.
 *  panic_fn: a function to  be called if, after waiting "maxwait"
 *            seconds, not all object refcnts are zero.
 * The caller must ensure that no one else holds references to the
 * set or any objects it contains.
 */
void
repl_objset_destroy(Repl_Objset **o, time_t maxwait, FNFree panic_fn)
{
	Repl_Objset_object *co = NULL;
	time_t now, stop_time;
	int really_gone;
	int loopcount;
	void *cookie;

	PR_ASSERT(NULL != o);
	PR_ASSERT(NULL != *o);

	time(&now);
	stop_time = now + maxwait;

	/*
	 * Loop over the objects until they all are actually gone,
	 * or until maxwait seconds have passed.
	 */
	really_gone = 0;
	loopcount = 0;

	while (now < stop_time)
	{
		void *cookie;

		PR_Lock((*o)->lock);

		if ((co = llistGetFirst((*o)->objects, &cookie)) == NULL)
		{
			really_gone = 1;
			PR_Unlock((*o)->lock);
			break;
		}
		while (NULL != co)
		{
			/* Set the deleted flag so the object isn't returned by iterator */
			co->flags |= REPL_OBJSET_OBJ_FLAG_DELETED;
			if (0 == co->refcnt)
			{
				/* Remove the object */
				co = removeCurrentObjectAndGetNextNolock ((*o), co, cookie);
					
			}
			else
				co = llistGetNext((*o)->objects, &cookie);
		}
		PR_Unlock((*o)->lock);
		time(&now);
		if (loopcount > 0)
		{
			DS_Sleep(PR_TicksPerSecond());
		}
		loopcount++;
	}

	if (!really_gone)
	{
		if (NULL != panic_fn)
		{
			/*
			 * Call the "aargh, this thing won't go away" panic
			 * function for each remaining object.
			 */
			PR_Lock((*o)->lock);
			co = llistGetFirst((*o)->objects, &cookie);
			while (NULL != co)
			{
				panic_fn(co->data);
				co = llistGetNext((*o)->objects, &cookie);
			}
			PR_Unlock((*o)->lock);
		}
	}
	else
	{
		/* Free the linked list */
		llistDestroy(&(*o)->objects, (*o)->destructor);
		PR_DestroyLock((*o)->lock);
		slapi_ch_free((void **)o);
	}
}
int main(int argc, char **argv)
{
    setvbuf(stdout, NULL, _IOLBF, 0);
#ifdef XP_UNIX
    unlimit();
#endif
    fprintf(stdout, "\n");

    unsigned long limit = 0; // no thread limit by default
    char *addr = NULL;
    PRBool log = PR_FALSE;
    LogLevel logLevel = LOGINFO;
    PLOptState *options;
    PRBool secure = PR_FALSE;
    PRBool NSTests = PR_FALSE; // don't execute Netscape tests by default
    PtrList<char> protlist; // list of security protocols
    PtrList<char> configlist; // list of configurations
    RegexList regexlist; // list of Sun tests/regex to load
    RegexList regexcludelist; // list of Sun tests/regex to exclude
    char* suitename = "suite1";
    PRInt32 concurrent = 0; // number of concurrent threads for each test. 0 means sequential, single-threaded
    PRInt32 delay = 0;
    PRInt32 split = 0;
    PRInt32 timeout = 0; // leave timeout unchanged by default
    char* cert=NULL;
    char* certpwd=NULL;
    char* cipherString = NULL;
    char* version = "ENTERPRISE";
    PRInt32 release = 41;
    PRInt32 hsp = 0; // SSL handshake period
    PRBool performance = PR_FALSE;
    PRInt32 maxtm = 0;
    PRUint16 af = PR_AF_INET;
    PRInt32 displayperiod=0;
    PRBool loop = PR_FALSE;

    Logger::logInitialize(logLevel);

    options = PL_CreateOptState(argc, argv, "X:C:h:H:l:c:d:n:w46r:sx:p:o:t:a:e:k:Ng:v:R:QPE:T:L:");
    long repeat = 1;
    while ( PL_GetNextOpt(options) == PL_OPT_OK)
    {
        switch(options->option)
        {
            case 'L':
                loop = PR_TRUE;
                if (options->value)
                    displayperiod  = (PRInt32) atoi(options->value);
                break;

            case 'E':
                if (options->value)
                    protlist.insert(strdup(options->value));
                break;

            case 'T':
                if (options->value)
                    maxtm  = (PRInt32) atoi(options->value);
                break;

            case 'H':
                if (options->value)
                    hsp  = (PRInt32) atoi(options->value);
                break;

            case 'v':
                if (options->value)
                    version = uppercase(strdup(options->value));
                break;

            case 'g':
                if (options->value)
                    configlist.insert(strdup(options->value));
                break;

            case 'x':
                if (options->value)
                    regexlist.add(options->value);
                break;

            case 'X':
                if (options->value)
                    regexcludelist.add(options->value);
                break;

            case 'w':
                log = PR_TRUE;
                break;

            case 'r':
                if (options->value)
                    repeat = atol(options->value);
                break;

            case 'e':
                if (options->value)
                    timeout = atol(options->value);
                break;

            case 'o':
                if (options->value)
                    split = atol(options->value);
                break;

            case 't':
                if (options->value)
                    delay = atol(options->value);
                break;

            case 'd':
                if (options->value)
                   suitename = strdup(options->value);
                break;

            case 'a':
                if (options->value)
                    arch = strdup(options->value);
                break;

            case 'N':
                NSTests = PR_TRUE;
                break;

            case 'h':
                if (options->value)
                    addr = strdup(options->value);
                break;

            case 'p':
                if (options->value)
                    concurrent = atol(options->value);
                else
                    concurrent = 1; // 1 thread per test
                break;

            case 'P':
                performance = PR_TRUE; // meaure performance only
                break;

            case 'l':
                if (options->value)
                    logLevel = (LogLevel)atoi(options->value);
                break;

            case 'R':
                if (options->value)
                    release = (PRInt32) atoi(options->value);
                break;

            case 's':
                secure = PR_TRUE;
                break;

            case 'n':
                if (options->value)
                    cert = strdup(options->value);
                break;

            case 'k':
                if (options->value)
                    certpwd = strdup(options->value);
                break;

            case 'c':
		if (options->value) {
                  cipherString = strdup(options->value);
                  if (PR_TRUE != EnableCipher(cipherString))
                  {
                         Logger::logError(LOGINFO, "Invalid cipher specified.\n");
                   };
                 }
 		 break;


            case 'C':
                if (options->value)
                    limit = atol(options->value);
                else
                    limit = 0; // no thread limit
                break;

	    case 'Q':
		printCipherOptions();
		break;

	    case '6':
                af = PR_AF_INET6;
		break;

	    case '4':
                af = PR_AF_INET;
		break;

        };
    };

    SecurityProtocols secprots;

    if (PR_TRUE == secure)
    {
        NSString str;
        str.append(suitename);
        str.append("/certs/client");
        secure = InitSecurity((char*)str.data(),
            cert,
            certpwd);
        if (PR_TRUE != secure)
            Logger::logError(LOGINFO, "Unable to initialize security.\n");

        if (protlist.entries())
        {
            secprots = protlist;
        };
    };

    PL_DestroyOptState(options);

    Logger::logInitialize(logLevel);
    nstime_init();

    if (!addr)
    {
        usage(argv[0]);
        return -1;
    };

    HttpServer server(addr, af);
    server.setSSL(secure);
    
    if (PR_FALSE == NSTests)
    {
        if (alltests)
            alltests->clear(); // cancel all the Netscape tests
        if (!regexlist.length())
            regexlist.add(".*");
    };

    if (!configlist.entries())
        configlist.insert("COMMON"); // if no config is specified, select default COMMON configuration

    Engine::globaltimeout = PR_TicksPerSecond()*timeout;

    SunTestSuite suite(configlist, suitename, regexlist, regexcludelist, arch, version, release, log, PR_TicksPerSecond()*timeout, split, delay, hsp, secprots, maxtm);
    PRInt32 percent = suite.runTests(server, concurrent, repeat, limit, performance, loop, displayperiod);

    return percent;
};
/*
 * FUNCTION: pkix_pl_OcspResponse_Create
 * DESCRIPTION:
 *
 *  This function transmits the OcspRequest pointed to by "request" and obtains
 *  an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient
 *  supports non-blocking I/O this function may store a non-NULL value at
 *  "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should
 *  make a subsequent call with the same value in "pNBIOContext" and
 *  "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may
 *  occur; the caller should persist until a return occurs with NULL stored at
 *  "pNBIOContext".
 *
 *  If a SEC_HttpClientFcn "responder" is supplied, it is used as the client
 *  to which the OCSP query is sent. If none is supplied, the default responder
 *  is used.
 *
 *  If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to
 *  verify the Cert received from the responder as the signer. If none is
 *  supplied, the default verification function is used.
 *
 *  The contents of "request" are ignored on calls subsequent to a WOULDBLOCK
 *  return, and the caller is permitted to supply NULL.
 *
 * PARAMETERS
 *  "request"
 *      Address of the OcspRequest for which a response is desired.
 *  "responder"
 *      Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP
 *      query.
 *  "verifyFcn"
 *      Address, if non-NULL, of the OcspResponse_VerifyCallback function to be
 *      used to verify the Cert of the OCSP responder.
 *  "pNBIOContext"
 *      Address at which platform-dependent information is stored for handling
 *      of non-blocking I/O. Must be non-NULL.
 *  "pOcspResponse"
 *      The address where the created OcspResponse is stored. Must be non-NULL.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns an OcspResponse Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_pl_OcspResponse_Create(
        PKIX_PL_OcspRequest *request,
        void *responder,
        PKIX_PL_OcspResponse_VerifyCallback verifyFcn,
        void **pNBIOContext,
        PKIX_PL_OcspResponse **pResponse,
        void *plContext)
{
        void *nbioContext = NULL;
        PKIX_PL_OcspResponse *ocspResponse = NULL;
        const SEC_HttpClientFcn *httpClient = NULL;
        const SEC_HttpClientFcnV1 *hcv1 = NULL;
        SECStatus rv = SECFailure;
        char *location = NULL;
        char *hostname = NULL;
        char *path = NULL;
        PRUint16 port = 0;
        SEC_HTTP_SERVER_SESSION serverSession = NULL;
        SEC_HTTP_REQUEST_SESSION requestSession = NULL;
        SECItem *encodedRequest = NULL;
        PRUint16 responseCode = 0;
        char *responseData = NULL;
        PRUint32 responseDataLen = 0;

        PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create");
        PKIX_NULLCHECK_TWO(pNBIOContext, pResponse);

        nbioContext = *pNBIOContext;
        *pNBIOContext = NULL;

        if (nbioContext != NULL) {

                ocspResponse = *pResponse;
                PKIX_NULLCHECK_ONE(ocspResponse);

                httpClient = ocspResponse->httpClient;
                serverSession = ocspResponse->serverSession;
                requestSession = ocspResponse->requestSession;
                PKIX_NULLCHECK_THREE(httpClient, serverSession, requestSession);

        } else {

                PKIX_NULLCHECK_ONE(request);

                PKIX_CHECK(pkix_pl_OcspRequest_GetEncoded
                        (request, &encodedRequest, plContext),
                        PKIX_OCSPREQUESTGETENCODEDFAILED);

                /* prepare initial message to HTTPClient */

                /* Is there a default responder and is it enabled? */
                if (!responder) {
                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE,
                                responder,
                                (void *)SEC_GetRegisteredHttpClient,
                                ());
                }

                httpClient = (const SEC_HttpClientFcn *)responder;

                if (httpClient && (httpClient->version == 1)) {

                        hcv1 = &(httpClient->fcnTable.ftable1);

                        PKIX_CHECK(pkix_pl_OcspRequest_GetLocation
                                (request, &location, plContext),
                                PKIX_OCSPREQUESTGETLOCATIONFAILED);

                        /* parse location -> hostname, port, path */    
                        PKIX_PL_NSSCALLRV(OCSPRESPONSE, rv, CERT_ParseURL,
                                (location, &hostname, &port, &path));

                        if ((hostname == NULL) || (path == NULL)) {
                                PKIX_ERROR(PKIX_URLPARSINGFAILED);
                        }

                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE,
                                rv,
                                hcv1->createSessionFcn,
                                (hostname, port, &serverSession));

                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE, rv, hcv1->createFcn,
                                (serverSession,
                                "http",
                                path,
                                "POST",
                                PR_TicksPerSecond() * 60,
                                &requestSession));

                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE, rv, hcv1->setPostDataFcn,
                                (requestSession,
                                (char *)encodedRequest->data,
                                encodedRequest->len,
                                "application/ocsp-request"));

                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        /* create a PKIX_PL_OcspResponse object */
                        PKIX_CHECK(PKIX_PL_Object_Alloc
                                    (PKIX_OCSPRESPONSE_TYPE,
                                    sizeof (PKIX_PL_OcspResponse),
                                    (PKIX_PL_Object **)&ocspResponse,
                                    plContext),
                                    PKIX_COULDNOTCREATEOBJECT);

                        PKIX_INCREF(request);
                        ocspResponse->request = request;
                        ocspResponse->httpClient = httpClient;
                        ocspResponse->serverSession = serverSession;
                        ocspResponse->requestSession = requestSession;
                        ocspResponse->verifyFcn = verifyFcn;
                        ocspResponse->handle = CERT_GetDefaultCertDB();
                        ocspResponse->encodedResponse = NULL;
                        ocspResponse->arena = NULL;
                        ocspResponse->producedAt = 0;
                        ocspResponse->producedAtDate = NULL;
                        ocspResponse->pkixSignerCert = NULL;
                        ocspResponse->nssOCSPResponse = NULL;
                        ocspResponse->signerCert = NULL;
                }
        }