// IOThread: this function creates a new TestListener object (on the new // thread), opens a channel, and does AsyncRead to it. void TestListener::IOThread( void *p ) { printf( "I/O thread (0x%08X) started...\n", (int)(void*)PR_GetCurrentThread() ); // Argument is pointer to the nsIEventQueue for the main thread. nsIEventQueue *mainThreadQ = static_cast<nsIEventQueue*>(p); // Create channel for random web page. nsCOMPtr<nsIChannel> channel = createChannel( (const char*)p ); if ( channel ) { // Create event queue. nsCOMPtr<nsIEventQueue> ioEventQ = createEventQueue(); if ( ioEventQ ) { // Create test listener. TestListener *testListener = new TestListener(); testListener->AddRef(); // Read the channel. printf( "Doing AsyncRead...\n" ); nsresult rv = channel->AsyncRead( testListener, 0 ); if ( NS_SUCCEEDED( rv ) ) { printf( "...AsyncRead completed OK\n" ); // Process events till testListener says stop. printf( "Start event loop on io thread %d...\n", testListener->mThreadNo ); while ( !testListener->mDone ) { PLEvent *event; ioEventQ->GetEvent( &event ); ioEventQ->HandleEvent( event ); } printf( "...io thread %d event loop exiting\n", testListener->mThreadNo ); } else { printf( "%s %d: AsyncRead failed on thread %d, rv=0x%08X\n", (char*)__FILE__, (int)__LINE__, testListener->mThreadNo, (int)rv ); } // Release the test listener. testListener->Release(); } } printf( "...I/O thread terminating\n" ); }
int main(int argc, char** argv){ EventQueue_t* queue = createEventQueue(3, 15); // Register an event to the "READ" (second phase) event stack addEvent(queue, EVENT_OPEN, myEventHandler); addEvent(queue, EVENT_READ, myEventHandler); addEvent(queue, EVENT_CLOSE, myEventHandler); triggerEvent(queue, EVENT_OPEN, "first"); triggerEvent(queue, EVENT_READ, "second"); triggerEvent(queue, EVENT_CLOSE, "third"); freeEventQueue(queue); return 0; }
int main( int argc, char* argv[] ) { setbuf( stdout, 0 ); if ( argc < 2 || argc > maxThreads + 1 ) { printf( "usage: testThreadedIO url1 <url2>...\n" "where <url#> is a location to be loaded on a separate thread\n" "limit is %d urls/threads", maxThreads ); return -1; } nsresult rv= (nsresult)-1; printf( "Test starting...\n" ); // Initialize XPCOM. printf( "Initializing XPCOM...\n" ); rv = NS_InitXPCOM2(nullptr, nullptr, nullptr); if ( NS_FAILED( rv ) ) { printf( "%s %d: NS_InitXPCOM failed, rv=0x%08X\n", (char*)__FILE__, (int)__LINE__, (int)rv ); return rv; } printf( "...XPCOM initialized OK\n" ); // Create the Event Queue for this thread... printf( "Creating event queue for main thread (0x%08X)...\n", (int)(void*)PR_GetCurrentThread() ); { nsCOMPtr<nsIEventQueue> mainThreadQ = createEventQueue(); if ( mainThreadQ ) { printf( "...main thread's event queue created OK\n" ); // Spawn threads to do I/O. int goodThreads = 0; PRThread *thread[ maxThreads ]; for ( int threadNo = 1; threadNo < argc; threadNo++ ) { printf( "Creating I/O thread %d to load %s...\n", threadNo, argv[threadNo] ); PRThread *ioThread = PR_CreateThread( PR_USER_THREAD, TestListener::IOThread, argv[threadNo], PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0 ); if ( ioThread ) { thread[ goodThreads++ ] = ioThread; printf( "...I/O thread %d (0x%08X) created OK\n", threadNo, (int)(void*)ioThread ); } else { printf( "%s %d: PR_CreateThread for thread %d failed\n", (char*)__FILE__, (int)__LINE__, threadNo ); } } // Wait for all the threads to terminate. for ( int joinThread = 0; joinThread < goodThreads; joinThread++ ) { printf( "Waiting for thread %d to terminate...\n", joinThread+1 ); PR_JoinThread( thread[ joinThread ] ); } } } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM // Shut down XPCOM. printf( "Shutting down XPCOM...\n" ); NS_ShutdownXPCOM( 0 ); printf( "...XPCOM shutdown complete\n" ); // Exit. printf( "...test complete, rv=0x%08X\n", (int)rv ); return rv; }