static void WaitCondVarThread(void *arg) { PRIntervalTime timeout = (PRIntervalTime) arg; PRIntervalTime elapsed; #if defined(XP_UNIX) || defined(WIN32) PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); PRInt32 elapsed_msecs; #endif #if defined(XP_UNIX) struct timeval end_time_tv; #endif #if defined(WIN32) struct _timeb end_time_tb; #endif PRLock *ml; PRCondVar *cv; ml = PR_NewLock(); if (ml == NULL) { fprintf(stderr, "PR_NewLock failed\n"); exit(1); } cv = PR_NewCondVar(ml); if (cv == NULL) { fprintf(stderr, "PR_NewCondVar failed\n"); exit(1); } PR_Lock(ml); PR_WaitCondVar(cv, timeout); PR_Unlock(ml); elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { fprintf(stderr, "timeout wrong\n"); exit(1); } #if defined(XP_UNIX) gettimeofday(&end_time_tv, NULL); elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; #endif #if defined(WIN32) _ftime(&end_time_tb); elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + (end_time_tb.millitm - start_time_tb.millitm); #endif #if defined(XP_UNIX) || defined(WIN32) if (elapsed_msecs + tolerance_msecs < timeout_msecs || elapsed_msecs > timeout_msecs + tolerance_msecs) { fprintf(stderr, "timeout wrong\n"); exit(1); } #endif PR_DestroyCondVar(cv); PR_DestroyLock(ml); if (debug_mode) { fprintf(stderr, "wait cond var thread (scope %d) done\n", PR_GetThreadScope(PR_GetCurrentThread())); } }
static void WaitMonitorThread(void *arg) { PRIntervalTime timeout = (PRIntervalTime) arg; PRIntervalTime elapsed; #if defined(XP_UNIX) || defined(WIN32) PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); PRInt32 elapsed_msecs; #endif #if defined(XP_UNIX) struct timeval end_time_tv; #endif #if defined(WIN32) && !defined(WINCE) struct _timeb end_time_tb; #endif PRMonitor *mon; mon = PR_NewMonitor(); if (mon == NULL) { fprintf(stderr, "PR_NewMonitor failed\n"); exit(1); } PR_EnterMonitor(mon); PR_Wait(mon, timeout); PR_ExitMonitor(mon); elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { fprintf(stderr, "timeout wrong\n"); exit(1); } #if defined(XP_UNIX) gettimeofday(&end_time_tv, NULL); elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; #endif #if defined(WIN32) #if defined(WINCE) elapsed_msecs = GetTickCount() - start_time_tick; #else _ftime(&end_time_tb); elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + (end_time_tb.millitm - start_time_tb.millitm); #endif #endif #if defined(XP_UNIX) || defined(WIN32) if (elapsed_msecs + tolerance_msecs < timeout_msecs || elapsed_msecs > timeout_msecs + tolerance_msecs) { fprintf(stderr, "timeout wrong\n"); exit(1); } #endif PR_DestroyMonitor(mon); if (debug_mode) { fprintf(stderr, "wait monitor thread (scope %d) done\n", PR_GetThreadScope(PR_GetCurrentThread())); } }
static void SleepThread(void *arg) { PRIntervalTime timeout = (PRIntervalTime) arg; PRIntervalTime elapsed; #if defined(XP_UNIX) || defined(WIN32) PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); PRInt32 elapsed_msecs; #endif #if defined(XP_UNIX) struct timeval end_time_tv; #endif #if defined(WIN32) && !defined(WINCE) struct _timeb end_time_tb; #endif if (PR_Sleep(timeout) == PR_FAILURE) { fprintf(stderr, "PR_Sleep failed\n"); exit(1); } elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { fprintf(stderr, "timeout wrong\n"); exit(1); } #if defined(XP_UNIX) gettimeofday(&end_time_tv, NULL); elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; #endif #if defined(WIN32) #if defined(WINCE) elapsed_msecs = GetTickCount() - start_time_tick; #else _ftime(&end_time_tb); elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + (end_time_tb.millitm - start_time_tb.millitm); #endif #endif #if defined(XP_UNIX) || defined(WIN32) if (elapsed_msecs + tolerance_msecs < timeout_msecs || elapsed_msecs > timeout_msecs + tolerance_msecs) { fprintf(stderr, "timeout wrong\n"); exit(1); } #endif if (debug_mode) { fprintf(stderr, "Sleep thread (scope %d) done\n", PR_GetThreadScope(PR_GetCurrentThread())); } }
static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg) { PRInt32 words; PRWord *registers; printf( "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread, (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i); registers = PR_GetGCRegisters(thread, 0, (int *)&words); if (registers) printf("Registers R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n", registers[0],registers[1],registers[2],registers[3]); printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread)); return PR_SUCCESS; }
static void WaitCMonitorThread(void *arg) { PRIntervalTime timeout = (PRIntervalTime) arg; PRIntervalTime elapsed; #if defined(XP_UNIX) || defined(WIN32) PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); PRInt32 elapsed_msecs; #endif #if defined(XP_UNIX) struct timeval end_time_tv; #endif #if defined(WIN32) struct _timeb end_time_tb; #endif int dummy; PR_CEnterMonitor(&dummy); PR_CWait(&dummy, timeout); PR_CExitMonitor(&dummy); elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { fprintf(stderr, "timeout wrong\n"); exit(1); } #if defined(XP_UNIX) gettimeofday(&end_time_tv, NULL); elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; #endif #if defined(WIN32) _ftime(&end_time_tb); elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + (end_time_tb.millitm - start_time_tb.millitm); #endif #if defined(XP_UNIX) || defined(WIN32) if (elapsed_msecs + tolerance_msecs < timeout_msecs || elapsed_msecs > timeout_msecs + tolerance_msecs) { fprintf(stderr, "timeout wrong\n"); exit(1); } #endif if (debug_mode) { fprintf(stderr, "wait cached monitor thread (scope %d) done\n", PR_GetThreadScope(PR_GetCurrentThread())); } }
static void PollThread(void *arg) { PRIntervalTime timeout = (PRIntervalTime) arg; PRIntervalTime elapsed; #if defined(XP_UNIX) || defined(WIN32) PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); PRInt32 elapsed_msecs; #endif #if defined(XP_UNIX) struct timeval end_time_tv; #endif #if defined(WIN32) && !defined(WINCE) struct _timeb end_time_tb; #endif PRFileDesc *sock; PRNetAddr addr; PRPollDesc pd; PRIntn rv; sock = PR_NewTCPSocket(); if (sock == NULL) { fprintf(stderr, "PR_NewTCPSocket failed\n"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.inet.family = PR_AF_INET; addr.inet.port = 0; addr.inet.ip = PR_htonl(PR_INADDR_ANY); if (PR_Bind(sock, &addr) == PR_FAILURE) { fprintf(stderr, "PR_Bind failed\n"); exit(1); } if (PR_Listen(sock, 5) == PR_FAILURE) { fprintf(stderr, "PR_Listen failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_READ; rv = PR_Poll(&pd, 1, timeout); if (rv != 0) { fprintf(stderr, "PR_Poll did not time out\n"); exit(1); } elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { fprintf(stderr, "timeout wrong\n"); exit(1); } #if defined(XP_UNIX) gettimeofday(&end_time_tv, NULL); elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; #endif #if defined(WIN32) #if defined(WINCE) elapsed_msecs = GetTickCount() - start_time_tick; #else _ftime(&end_time_tb); elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + (end_time_tb.millitm - start_time_tb.millitm); #endif #endif #if defined(XP_UNIX) || defined(WIN32) if (elapsed_msecs + tolerance_msecs < timeout_msecs || elapsed_msecs > timeout_msecs + tolerance_msecs) { fprintf(stderr, "timeout wrong\n"); exit(1); } #endif if (PR_Close(sock) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } if (debug_mode) { fprintf(stderr, "Poll thread (scope %d) done\n", PR_GetThreadScope(PR_GetCurrentThread())); } }
NSAPI_PUBLIC int filter_insert(SYS_NETFD fd, pblock *pb, Session *sn, Request *rq, void *data, const Filter *filter) { // Use session's csd if caller didn't specify an fd if (!fd && sn && sn->csd_open == 1) fd = sn->csd; if (!fd || !filter) return REQ_NOACTION; PR_ASSERT((void *)filter == (void *)&filter->priomethods); // Check Request-based filter preconditions if (rq) { // Request-based filters must be associated with a session if (rq && !sn) { NsprError::setError(PR_INVALID_ARGUMENT_ERROR, XP_GetAdminStr(DBT_MissingSession)); return REQ_ABORTED; } // Don't insert FILTER_CONTENT_CODING and lower filters on child // requests if (INTERNAL_REQUEST(rq) && filter->order < FILTER_SUBREQUEST_BOUNDARY) return REQ_NOACTION; } // Check for a NativeThread="yes" filter running on a local thread if (filter->flags & FILTER_USE_NATIVE_THREAD) { if (!_filter_logged_native_thread_issue) { // XXX this is inefficient if (PR_GetThreadScope(PR_GetCurrentThread()) == PR_LOCAL_THREAD) { _filter_logged_native_thread_issue = PR_TRUE; log_error(LOG_MISCONFIG, "filter-insert", sn, rq, XP_GetAdminStr(DBT_FilterXRequiresNativeThreads), filter->name); } } } // Find where the filter belongs in the filter stack PRFileDesc *bottom = NULL; PRFileDesc *unknown = NULL; PRFileDesc *position; for (position = fd; position; position = position->lower) { // Find a layer we can determine the order of int order = filter_iolayer_order(position); if (order < 0) { if (!unknown) unknown = position; continue; } // Does the new layer belong above this layer? if (filter->order >= order) { // If there are non-filter IO layers directly above this layer, // the filter belongs above them if (unknown) position = unknown; break; } unknown = NULL; // This may be the bottom-most layer with a known order bottom = position; } if (!position) { if (!bottom) { // We're the first layer, we go on top position = fd; } else if (bottom->lower) { // Insert below the lowest layer with a known order position = bottom->lower; } else { // Nowhere to install the filter NsprError::setError(PR_INVALID_ARGUMENT_ERROR, XP_GetAdminStr(DBT_InvalidFilterStack)); return REQ_ABORTED; } } // Get an IO layer for the filter PRFileDesc *iolayer = filter_alloc_filter_iolayer(sn, filter); if (!iolayer) return REQ_ABORTED; // Initialize filter layer context FilterContext *context = filter_create_context(sn, rq, data, filter, (FilterLayer *)iolayer); if (!context) { // Dispose of the IO layer filter_free_iolayer(sn, iolayer); return REQ_ABORTED; } // Install the filter's IO layer if (filter_insert_iolayer(position, &iolayer) != REQ_PROCEED) { // Destroy the filter's context filter_destroy_context((FilterLayer *)iolayer); // Dispose of the IO layer filter_free_iolayer(sn, iolayer); return REQ_ABORTED; } PR_ASSERT(iolayer->methods == &filter->priomethods); // Give the filter a chance to initialize int rv = filter->insert((FilterLayer *)iolayer, pb ? pb : _empty_pb); if (rv != REQ_PROCEED) { // Destroy the filter's context filter_destroy_context((FilterLayer *)iolayer); // Remove the IO layer from the stack iolayer = filter_extract_iolayer(iolayer); // Dispose of the IO layer filter_free_iolayer(sn, iolayer); return rv; } // Let the NSAPIRequest know it needs to clean up after a filter if (rq) { NSAPIRequest *nrq = (NSAPIRequest *)rq; NSAPISession *nsn = (NSAPISession *)sn; PR_ASSERT(nrq->filter_sn == NULL || nrq->filter_sn == sn); nrq->filter_sn = sn; } // If the new filter doesn't call the callbacks... if (!(filter->flags & FILTER_CALLS_CALLBACKS)) { // If the new filter was added to the top of the stack... if (position == fd && position->lower && position->lower->identity == _filter_identity) { // If the new filter is masking a filter that does call the // callbacks (i.e. httpfilter)... FilterLayer *lower = (FilterLayer *)position->lower; if (lower->filter->flags & FILTER_CALLS_CALLBACKS) { // Add a callback filter to the top of the stack filter_insert(fd, NULL, lower->context->sn, NULL, NULL, _filter_callback); } } } return rv; }
RCThread::Scope RCThread::GetScope() const { return (RCThread::Scope)PR_GetThreadScope(identity); }
static void AcceptThread(void *arg) { PRIntervalTime timeout = (PRIntervalTime) arg; PRIntervalTime elapsed; #if defined(XP_UNIX) || defined(WIN32) PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); PRInt32 elapsed_msecs; #endif #if defined(XP_UNIX) struct timeval end_time_tv; #endif #if defined(WIN32) struct _timeb end_time_tb; #endif PRFileDesc *sock; PRNetAddr addr; PRFileDesc *accepted; sock = PR_NewTCPSocket(); if (sock == NULL) { fprintf(stderr, "PR_NewTCPSocket failed\n"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.inet.family = PR_AF_INET; addr.inet.port = 0; addr.inet.ip = PR_htonl(PR_INADDR_ANY); if (PR_Bind(sock, &addr) == PR_FAILURE) { fprintf(stderr, "PR_Bind failed\n"); exit(1); } if (PR_Listen(sock, 5) == PR_FAILURE) { fprintf(stderr, "PR_Listen failed\n"); exit(1); } accepted = PR_Accept(sock, NULL, timeout); if (accepted != NULL || PR_GetError() != PR_IO_TIMEOUT_ERROR) { fprintf(stderr, "PR_Accept did not time out\n"); exit(1); } elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { fprintf(stderr, "timeout wrong\n"); exit(1); } #if defined(XP_UNIX) gettimeofday(&end_time_tv, NULL); elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; #endif #if defined(WIN32) _ftime(&end_time_tb); elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + (end_time_tb.millitm - start_time_tb.millitm); #endif #if defined(XP_UNIX) || defined(WIN32) if (elapsed_msecs + tolerance_msecs < timeout_msecs || elapsed_msecs > timeout_msecs + tolerance_msecs) { fprintf(stderr, "timeout wrong\n"); exit(1); } #endif if (PR_Close(sock) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } if (debug_mode) { fprintf(stderr, "Accept thread (scope %d) done\n", PR_GetThreadScope(PR_GetCurrentThread())); } }