Esempio n. 1
0
//static
void LLCommon::initClass()
{
	LLMemory::initClass();
	if (!sAprInitialized)
	{
		ll_init_apr();
		sAprInitialized = TRUE;
	}
	LLTimer::initClass();
	LLThreadSafeRefCount::initThreadSafeRefCount();
// 	LLWorkerThread::initClass();
// 	LLFrameCallbackManager::initClass();
}
Esempio n. 2
0
//static
void LLCommon::initClass()
{
	LLMemory::initClass();
	if (!sAprInitialized)
	{
		ll_init_apr();
		sAprInitialized = TRUE;
	}
	LLTimer::initClass();
	LLThreadSafeRefCount::initThreadSafeRefCount();
	assert_main_thread();		// Make sure we record the main thread
	if (!sMasterThreadRecorder)
	{
		sMasterThreadRecorder = new LLTrace::ThreadRecorder();
		LLTrace::set_master_thread_recorder(sMasterThreadRecorder);
	}
}
Esempio n. 3
0
		LLMessageSystemTestData()
		{
			static bool init = false;
			if(! init)
			{
				ll_init_apr();
				init_prehash_data();
				init = true;
			}

			// currently test disconnected message system
			start_messaging_system("notafile", 13035,
								   LL_VERSION_MAJOR,
								   LL_VERSION_MINOR,        
								   LL_VERSION_PATCH,        
								   FALSE,        
								   "notasharedsecret");
		}
		static LLMessageTemplate defaultTemplate()
		{
			static bool init = false;
			if(! init)
			{
				ll_init_apr();
				start_messaging_system("notafile", 13035,
									   LL_VERSION_MAJOR,
									   LL_VERSION_MINOR,        
									   LL_VERSION_PATCH,        
									   FALSE,        
									   "notasharedsecret",
									   NULL,
									   false);
				//init_prehash_data();
				init = true;
			}
			return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
		}
Esempio n. 5
0
		LLMessageSystemTestData()
		{
			static bool init = false;
			if(!init)
			{
				ll_init_apr();
				//init_prehash_data();
				init = true;
			}
			const F32 circuit_heartbeat_interval=5;
			const F32 circuit_timeout=100;


			// currently test disconnected message system
			start_messaging_system("notafile", 13035,
								   LL_VERSION_MAJOR,
								   LL_VERSION_MINOR,        
								   LL_VERSION_PATCH,        
								   FALSE,        
								   "notasharedsecret",
								   NULL,
								   false,
								   circuit_heartbeat_interval,
								   circuit_timeout
								   );
			// generate temp dir
			std::ostringstream ostr;
#if LL_WINDOWS
			mSep = "\\";
			ostr << "C:" << mSep;
#else
			mSep = "/";
			ostr << mSep << "tmp" << mSep;
#endif
			LLUUID random;
			random.generate();
			ostr << "message-test-" << random;
			mTestConfigDir = ostr.str();
			LLFile::mkdir(mTestConfigDir);
			writeConfigFile(LLSD());
			LLMessageConfig::initClass("simulator", ostr.str());
		}
		static LLMessageTemplate defaultTemplate()
		{
			static bool init = false;
			if(! init)
			{
				ll_init_apr();
				const F32 circuit_heartbeat_interval=5;
				const F32 circuit_timeout=100;

				start_messaging_system("notafile", 13035,
									   LL_VERSION_MAJOR,
									   LL_VERSION_MINOR,        
									   LL_VERSION_PATCH,        
									   FALSE,        
									   "notasharedsecret",
									   NULL,
									   false,
									   circuit_heartbeat_interval,
									   circuit_timeout);
				//init_prehash_data();
				init = true;
			}
			return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
		}
Esempio n. 7
0
int main(int argc, char** argv)
{
	// List of input and output files
	std::list<std::string> input_filenames;
	std::list<std::string> output_filenames;
	// Other optional parsed arguments
	bool analyze_performance = false;
	bool image_stats = false;
	int* region = NULL;
	int discard_level = -1;
	int precincts_size = -1;
	int blocks_size = -1;
	int levels = 0;
	bool reversible = false;

	// Init whatever is necessary
	ll_init_apr();
	LLImage::initClass();
	LogThread* fast_timer_log_thread = NULL;	// For performance and metric gathering

	// Analyze command line arguments
	for (int arg = 1; arg < argc; ++arg)
	{
		if (!strcmp(argv[arg], "--help") || !strcmp(argv[arg], "-h"))
		{
            // Send the usage to standard out
            std::cout << USAGE << std::endl;
			return 0;
		}
		else if ((!strcmp(argv[arg], "--input") || !strcmp(argv[arg], "-i")) && arg < argc-1)
		{
			std::string file_name = argv[arg+1];
			while (file_name[0] != '-')		// if arg starts with '-', we consider it's not a file name but some other argument
			{
				// std::cout << "input file name : " << file_name << std::endl;				
				store_input_file(input_filenames, file_name);
				arg += 1;					// Skip that arg now we know it's a file name
				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
					break;
				file_name = argv[arg+1];	// Next argument and loop over
			}
		}
		else if ((!strcmp(argv[arg], "--output") || !strcmp(argv[arg], "-o")) && arg < argc-1)
		{
			std::string file_name = argv[arg+1];
			while (file_name[0] != '-')		// if arg starts with '-', we consider it's not a file name but some other argument
			{
				// std::cout << "output file name : " << file_name << std::endl;				
				store_output_file(output_filenames, input_filenames, file_name);
				arg += 1;					// Skip that arg now we know it's a file name
				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
					break;
				file_name = argv[arg+1];	// Next argument and loop over
			}
		}
		else if ((!strcmp(argv[arg], "--region") || !strcmp(argv[arg], "-r")) && arg < argc-1)
		{
			std::string value_str = argv[arg+1];
			int index = 0;
			region = new int[4];
			while (value_str[0] != '-')		// if arg starts with '-', it's the next option
			{
				int value = atoi(value_str.c_str());
				region[index++] = value;
				arg += 1;					// Definitely skip that arg now we know it's a number
				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
					break;
				if (index == 4)				// Break out of the loop if we captured 4 values already
					break;
				value_str = argv[arg+1];	// Next argument and loop over
			}
			if (index != 4)
			{
				std::cout << "--region arguments invalid" << std::endl;
				delete [] region;
				region = NULL;
			}
		}
		else if (!strcmp(argv[arg], "--discard_level") || !strcmp(argv[arg], "-d"))
		{
			std::string value_str;
			if ((arg + 1) < argc)
			{
				value_str = argv[arg+1];
			}
			if (((arg + 1) >= argc) || (value_str[0] == '-'))
			{
				std::cout << "No valid --discard_level argument given, discard_level ignored" << std::endl;
			}
			else
			{
				discard_level = atoi(value_str.c_str());
				// Clamp to the values accepted by the viewer
				discard_level = llclamp(discard_level,0,5);
			}
		}
		else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p"))
		{
			std::string value_str;
			if ((arg + 1) < argc)
			{
				value_str = argv[arg+1];
			}
			if (((arg + 1) >= argc) || (value_str[0] == '-'))
			{
				std::cout << "No valid --precincts argument given, precincts ignored" << std::endl;
			}
			else
			{
				precincts_size = atoi(value_str.c_str());
			}
		}
		else if (!strcmp(argv[arg], "--blocks") || !strcmp(argv[arg], "-b"))
		{
			std::string value_str;
			if ((arg + 1) < argc)
			{
				value_str = argv[arg+1];
			}
			if (((arg + 1) >= argc) || (value_str[0] == '-'))
			{
				std::cout << "No valid --blocks argument given, blocks ignored" << std::endl;
			}
			else
			{
				blocks_size = atoi(value_str.c_str());
			}
		}
		else if (!strcmp(argv[arg], "--levels") || !strcmp(argv[arg], "-l"))
		{
			std::string value_str;
			if ((arg + 1) < argc)
			{
				value_str = argv[arg+1];
			}
			if (((arg + 1) >= argc) || (value_str[0] == '-'))
			{
				std::cout << "No valid --levels argument given, default (5) will be used" << std::endl;
			}
			else
			{
				levels = atoi(value_str.c_str());
			}
		}
		else if (!strcmp(argv[arg], "--reversible") || !strcmp(argv[arg], "-rev"))
		{
			reversible = true;
		}
		else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log"))
		{
			// '--logmetrics' needs to be specified with a named test metric argument
			// Note: for the moment, only ImageCompressionTester has been tested
			std::string test_name;
			if ((arg + 1) < argc)
			{
				test_name = argv[arg+1];
			}
			if (((arg + 1) >= argc) || (test_name[0] == '-'))
			{
				// We don't have an argument left in the arg list or the next argument is another option
				std::cout << "No --logmetrics argument given, no perf data will be gathered" << std::endl;
			}
			else
			{
				LLFastTimer::sMetricLog = TRUE;
				LLFastTimer::sLogName = test_name;
				arg += 1;					// Skip that arg now we know it's a valid test name
				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list
					break;
			}
		}
		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a"))
		{
			analyze_performance = true;
		}
		else if (!strcmp(argv[arg], "--image-stats") || !strcmp(argv[arg], "-s"))
		{
			image_stats = true;
		}
	}
		
	// Check arguments consistency. Exit with proper message if inconsistent.
	if (input_filenames.size() == 0)
	{
		std::cout << "No input file, nothing to do -> exit" << std::endl;
		return 0;
	}
	if (analyze_performance && !LLFastTimer::sMetricLog)
	{
		std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -a) -> exit" << std::endl;
		return 0;
	}
	

	// Create the logging thread if required
	if (LLFastTimer::sMetricLog)
	{
		LLFastTimer::sLogLock = new LLMutex(NULL);
		fast_timer_log_thread = new LogThread(LLFastTimer::sLogName);
		fast_timer_log_thread->start();
	}
	
	// Perform action on each input file
	std::list<std::string>::iterator in_file  = input_filenames.begin();
	std::list<std::string>::iterator out_file = output_filenames.begin();
	std::list<std::string>::iterator in_end = input_filenames.end();
	std::list<std::string>::iterator out_end = output_filenames.end();
	for (; in_file != in_end; ++in_file, ++out_file)
	{
		// Load file
		LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);
		if (!raw_image)
		{
			std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
			continue;
		}
	
		// Save file
		if (out_file != out_end)
		{
			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, levels, reversible, image_stats))
			{
				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;
			}
			else
			{
				std::cout << *in_file << " -> " << *out_file << std::endl;
			}
		}
	}

	// Output perf data if requested by user
	if (analyze_performance)
	{
		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
		std::string current_name  = LLFastTimer::sLogName + ".slp"; 
		std::string report_name   = LLFastTimer::sLogName + "_report.csv";
		
		std::cout << "Analyzing performance, check report in : " << report_name << std::endl;

		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name);
	}
	
	// Stop the perf gathering system if needed
	if (LLFastTimer::sMetricLog)
	{
		LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName);
		sAllDone = true;
	}
	
	// Cleanup and exit
	LLImage::cleanupClass();
	if (fast_timer_log_thread)
	{
		fast_timer_log_thread->shutdown();
	}
	
	return 0;
}
Esempio n. 8
0
bool LLAres::process(U64 timeout)
{
	if (!gAPRPoolp)
	{
		ll_init_apr();
	}

	ares_socket_t socks[ARES_GETSOCK_MAXNUM];
	apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
	apr_int32_t nsds = 0;	
	int nactive = 0;
	int bitmask;

	bitmask = ares_getsock(chan_, socks, ARES_GETSOCK_MAXNUM);

	if (bitmask == 0)
	{
		return nsds > 0;
	}

	apr_status_t status;
	LLAPRPool pool;
	status = pool.getStatus() ;
	ll_apr_assert_status(status);

	for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
	{
		if (ARES_GETSOCK_READABLE(bitmask, i))
		{
			aprFds[nactive].reqevents = APR_POLLIN | APR_POLLERR;
		}
		else if (ARES_GETSOCK_WRITABLE(bitmask, i))
		{
			aprFds[nactive].reqevents = APR_POLLOUT | APR_POLLERR;
		} else {
			continue;
		}

		apr_socket_t *aprSock = NULL;

		status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
		if (status != APR_SUCCESS)
		{
			ll_apr_warn_status(status);
			return nsds > 0;
		}

		aprFds[nactive].desc.s = aprSock;
		aprFds[nactive].desc_type = APR_POLL_SOCKET;
		aprFds[nactive].p = pool.getAPRPool();
		aprFds[nactive].rtnevents = 0;
		aprFds[nactive].client_data = &socks[i];

		nactive++;
	}

	if (nactive > 0)
	{
		status = apr_poll(aprFds, nactive, &nsds, timeout);

		if (status != APR_SUCCESS && status != APR_TIMEUP)
		{
			ll_apr_warn_status(status);
		}

		for (int i = 0; i < nactive; i++)
		{
			int evts = aprFds[i].rtnevents;
			int ifd = (evts & (APR_POLLIN | APR_POLLERR))
				? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD;
			int ofd = (evts & (APR_POLLOUT | APR_POLLERR))
				? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD;
					
			ares_process_fd(chan_, ifd, ofd);
		}
	}

	return nsds > 0;
}
Esempio n. 9
0
int main(int argc, char **argv)
#endif
{
	ll_init_apr();

	// Set up llerror logging
	{
		LLError::initForApplication(".");
		LLError::setDefaultLevel(LLError::LEVEL_INFO);
//		LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
//		LLError::logToFile("slplugin.log");
	}

#if LL_WINDOWS
	if( strlen( lpCmdLine ) == 0 )
	{
		LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL;
	};

	U32 port = 0;
	if(!LLStringUtil::convertToU32(lpCmdLine, port))
	{
		LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
	};

	// Insert our exception handler into the system so this plugin doesn't
	// display a crash message if something bad happens. The host app will
	// see the missing heartbeat and log appropriately.
	initExceptionHandler();
#elif LL_DARWIN || LL_LINUX
	if(argc < 2)
	{
		LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL;
	}

	U32 port = 0;
	if(!LLStringUtil::convertToU32(argv[1], port))
	{
		LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
	}

	// Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown.
	signal(SIGILL, &crash_handler);		// illegal instruction
# if LL_DARWIN
	signal(SIGEMT, &crash_handler);		// emulate instruction executed
# endif // LL_DARWIN
	signal(SIGFPE, &crash_handler);		// floating-point exception
	signal(SIGBUS, &crash_handler);		// bus error
	signal(SIGSEGV, &crash_handler);	// segmentation violation
	signal(SIGSYS, &crash_handler);		// non-existent system call invoked
#endif

#if LL_DARWIN
	setupCocoa();
	createAutoReleasePool();
#endif

	LLPluginProcessChild *plugin = new LLPluginProcessChild();

	plugin->init(port);

#if LL_DARWIN
		deleteAutoReleasePool();
#endif

	LLTimer timer;
	timer.start();

#if LL_WINDOWS
	checkExceptionHandler();
#endif

#if LL_DARWIN
	// If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground.
	// Use this to track the current frontmost window and bring this process to the front if it changes.
	WindowRef front_window = NULL;
	WindowGroupRef layer_group = NULL;
	int window_hack_state = 0;
	CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group);
	if(layer_group)
	{
		// Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube)
		SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer"));
		SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);		
	}
#endif

#if LL_DARWIN
	EventTargetRef event_target = GetEventDispatcherTarget();
#endif
	while(!plugin->isDone())
	{
#if LL_DARWIN
		createAutoReleasePool();
#endif
		timer.reset();
		plugin->idle();
#if LL_DARWIN
		{
			// Some plugins (webkit at least) will want an event loop.  This qualifies.
			EventRef event;
			if(ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &event) == noErr)
			{
				SendEventToEventTarget (event, event_target);
				ReleaseEvent(event);
			}
			
			// Check for a change in this process's frontmost window.
			if(FrontWindow() != front_window)
			{
				ProcessSerialNumber self = { 0, kCurrentProcess };
				ProcessSerialNumber parent = { 0, kNoProcess };
				ProcessSerialNumber front = { 0, kNoProcess };
				Boolean this_is_front_process = false;
				Boolean parent_is_front_process = false;
				{
					// Get this process's parent
					ProcessInfoRec info;
					info.processInfoLength = sizeof(ProcessInfoRec);
					info.processName = NULL;
					info.processAppSpec = NULL;
					if(GetProcessInformation( &self, &info ) == noErr)
					{
						parent = info.processLauncher;
					}
					
					// and figure out whether this process or its parent are currently frontmost
					if(GetFrontProcess(&front) == noErr)
					{
						(void) SameProcess(&self, &front, &this_is_front_process);
						(void) SameProcess(&parent, &front, &parent_is_front_process);
					}
				}
								
				if((FrontWindow() != NULL) && (front_window == NULL))
				{
					// Opening the first window
					
					if(window_hack_state == 0)
					{
						// Next time through the event loop, lower the window group layer
						window_hack_state = 1;
					}

					if(layer_group)
					{
						SetWindowGroup(FrontWindow(), layer_group);
					}
					
					if(parent_is_front_process)
					{
						// Bring this process's windows to the front.
						(void) SetFrontProcess( &self );
					}

					ActivateWindow(FrontWindow(), true);					
				}
				else if((FrontWindow() == NULL) && (front_window != NULL))
				{
					// Closing the last window
					
					if(this_is_front_process)
					{
						// Try to bring this process's parent to the front
						(void) SetFrontProcess(&parent);
					}
				}
				else if(window_hack_state == 1)
				{
					if(layer_group)
					{
						// Set the window group level back to something less extreme
						SetWindowGroupLevel(layer_group, kCGNormalWindowLevel);
					}
					window_hack_state = 2;
				}

				front_window = FrontWindow();

			}
		}
#endif
		F64 elapsed = timer.getElapsedTimeF64();
		F64 remaining = plugin->getSleepTime() - elapsed;

		if(remaining <= 0.0f)
		{
			// We've already used our full allotment.
//			LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL;

			// Still need to service the network...
			plugin->pump();
		}
		else
		{

//			LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL;
//			timer.reset();

			// This also services the network as needed.
			plugin->sleep(remaining);

//			LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" <<  LL_ENDL;
		}

#if LL_WINDOWS
	// More agressive checking of interfering exception handlers.
	// Doesn't appear to be required so far - even for plugins
	// that do crash with a single call to the intercept
	// exception handler such as QuickTime.
	//checkExceptionHandler();
#endif

#if LL_DARWIN
		deleteAutoReleasePool();
#endif
	}

	delete plugin;

	ll_cleanup_apr();

	return 0;
}
Esempio n. 10
0
int main( int argc, char* argv[] )
{

	ll_init_apr();

	// Set up llerror logging 
	{
		LLError::initForApplication(".");
		LLError::setDefaultLevel(LLError::LEVEL_INFO);
	}
	
	std::string launcher_name;
	std::string plugin_name;

	if(argc >= 3)
	{
		launcher_name = argv[1];
		plugin_name = argv[2];
	}
	else
	{
#if LL_DARWIN
		// hardcoding the testbed arguments by default
		launcher_name = "plugin_process_host";
		plugin_name = "libdemo_media_plugin_quicktime.dylib";
#elif LL_WINDOWS
		// hardcoding the testbed arguments by default
		launcher_name = "plugin_process_host.exe";
		plugin_name = "demo_media_plugin_quicktime.dll";
#else
		LL_ERRS("plugin_process_launcher") << "usage: " << argv[0] << " launcher_filename plugin_filename" << LL_ENDL;
#endif
	}

	gApplication = new mediaPluginTest(launcher_name, plugin_name);

	if ( gApplication )
	{
		glutInit( &argc, argv );
		glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );

		glutInitWindowPosition( 80, 0 );
		glutInitWindowSize( gApplication->getAppWindowWidth(), gApplication->getAppWindowHeight() );

		glutCreateWindow( gApplication->getAppWindowName().c_str() );

		glutKeyboardFunc( glutKeyboard );

		glutMouseFunc( glutMouseButton );
		glutPassiveMotionFunc( glutMouseMove );
		glutMotionFunc( glutMouseMove );

		glutDisplayFunc( glutDisplay );
		glutReshapeFunc( glutReshape );

		glutIdleFunc( glutIdle );

		gApplication->initGL();

		glutMainLoop();

		delete gApplication;
	};

	ll_cleanup_apr();

	return 0;
}
Esempio n. 11
0
int main(int argc, char **argv)
#endif
{
	ll_init_apr();

	// Set up llerror logging
	{
		LLError::initForApplication(".");
		LLError::setDefaultLevel(LLError::LEVEL_INFO);
//		LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
//		LLError::logToFile("slplugin.log");
	}

#if LL_WINDOWS
	if( strlen( lpCmdLine ) == 0 )
	{
		LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL;
	};

	U32 port = 0;
	if(!LLStringUtil::convertToU32(lpCmdLine, port))
	{
		LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
	};

	// Insert our exception handler into the system so this plugin doesn't
	// display a crash message if something bad happens. The host app will
	// see the missing heartbeat and log appropriately.
	initExceptionHandler();
#elif LL_DARWIN || LL_LINUX
	if(argc < 2)
	{
		LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL;
	}

	U32 port = 0;
	if(!LLStringUtil::convertToU32(argv[1], port))
	{
		LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
	}

	// Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown.
	signal(SIGILL, &crash_handler);		// illegal instruction
# if LL_DARWIN
	signal(SIGEMT, &crash_handler);		// emulate instruction executed
# endif // LL_DARWIN
	signal(SIGFPE, &crash_handler);		// floating-point exception
	signal(SIGBUS, &crash_handler);		// bus error
	signal(SIGSEGV, &crash_handler);	// segmentation violation
	signal(SIGSYS, &crash_handler);		// non-existent system call invoked
#endif

	LLPluginProcessChild *plugin = new LLPluginProcessChild();

	plugin->init(port);

	LLTimer timer;
	timer.start();

#if LL_WINDOWS
	checkExceptionHandler();
#endif

#if LL_DARWIN
	EventTargetRef event_target = GetEventDispatcherTarget();
#endif
	while(!plugin->isDone())
	{
		timer.reset();
		plugin->idle();
#if LL_DARWIN
		{
			// Some plugins (webkit at least) will want an event loop.  This qualifies.
			EventRef event;
			if(ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &event) == noErr)
			{
				SendEventToEventTarget (event, event_target);
				ReleaseEvent(event);
			}
		}
#endif
		F64 elapsed = timer.getElapsedTimeF64();
		F64 remaining = plugin->getSleepTime() - elapsed;

		if(remaining <= 0.0f)
		{
			// We've already used our full allotment.
//			LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL;

			// Still need to service the network...
			plugin->pump();
		}
		else
		{

//			LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL;
//			timer.reset();

			// This also services the network as needed.
			plugin->sleep(remaining);

//			LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" <<  LL_ENDL;
		}

#if LL_WINDOWS
	// More agressive checking of interfering exception handlers.
	// Doesn't appear to be required so far - even for plugins
	// that do crash with a single call to the intercept
	// exception handler such as QuickTime.
	//checkExceptionHandler();
#endif
	}

	delete plugin;

	ll_cleanup_apr();

	return 0;
}
int main(int argc, char **argv)
{
	ll_init_apr();

	// Set up llerror logging 
	{
		LLError::initForApplication(".");
		LLError::setDefaultLevel(LLError::LEVEL_INFO);
	}
	
	std::string launcher_name;
	std::string plugin_name;

	if(argc >= 3)
	{
		launcher_name = argv[1];
		plugin_name = argv[2];
	}
	else
	{
#if LL_DARWIN
		// hardcoding the testbed arguments by default
		launcher_name = "plugin_process_host";
		plugin_name = "libdemo_plugin.dylib";
#elif LL_WINDOWS
		// hardcoding the testbed arguments by default
		launcher_name = "plugin_process_host.exe";
		plugin_name = "demo_plugin.dll";
#else
		LL_ERRS("plugin_process_launcher") << "usage: " << argv[0] << " launcher_filename plugin_filename" << LL_ENDL;
#endif
	}

	PluginProcessLauncherMessageReceiver receiver;
	
	gServicePump = new LLPumpIO(gAPRPoolp);
	gServicePump->prime(gAPRPoolp);

	gPlugin = new LLPluginProcessParent(gServicePump, &receiver);

	State state = STATE_STARTUP;
	while(state != STATE_DONE)
	{
		switch(state)
		{
			case STATE_STARTUP:
				LL_INFOS("plugin_process_launcher") << "startup" << LL_ENDL;
				gPlugin->init(launcher_name, plugin_name);
				state = STATE_ADD_MEMORY;
			break;
			
			case STATE_ADD_MEMORY:
				if(gPlugin->isRunning())
				{
					LL_INFOS("plugin_process_launcher") << "adding shared memory" << LL_ENDL;
					gPlugin->addSharedMemory(SHARED_MEMORY_SIZE);
					state = STATE_RUNNING;
				}
			break;
			
			case STATE_RUNNING:
			{
				volatile unsigned char *addr = (unsigned char*)gPlugin->getSharedMemoryAddress(SHARED_MEMORY_NAME);
				if(addr != NULL)
				{
					int val = (int)(addr[0]);
					if(val >= 16)
					{
						state = STATE_REMOVE_MEMORY;
					}
					else
					{
						LL_INFOS("plugin_process_launcher") << "running, value from shared memory is " << val << LL_ENDL;
					}
				}
			}
			break;
			
			case STATE_REMOVE_MEMORY:
				LL_INFOS("plugin_process_launcher") << "removing shared memory" << LL_ENDL;
				gPlugin->removeSharedMemory(SHARED_MEMORY_NAME);
				state = STATE_SHUTDOWN;
			break;
			
			case STATE_SHUTDOWN:
			{
				volatile unsigned char *addr = (unsigned char*)gPlugin->getSharedMemoryAddress(SHARED_MEMORY_NAME);
				if(addr == NULL)
				{
					LL_INFOS("plugin_process_launcher") << "sending shutdown request" << LL_ENDL;
					gPlugin->shutdownRequest();
					state = STATE_CLEANUP;
				}
			}
			break;
			
			case STATE_CLEANUP:
				if(gPlugin->isDone())
				{
					LL_INFOS("plugin_process_launcher") << "plugin is done" << LL_ENDL;
					state = STATE_DONE;
				}
			break;
			
			case STATE_DONE:
				// should never reach here -- the while() should exit first.
			break;
		}
		
		// Do this every time through the loop
		if(state != STATE_DONE)
		{
			gServicePump->pump();
			gServicePump->callback();
			gPlugin->idle();
			ms_sleep(100);
		}
	}

	delete gPlugin;
	
	ll_cleanup_apr();
	
}
Esempio n. 13
0
int main(int argc, char **argv)
{
	LLError::initForApplication(".");
	LLError::setFatalFunction(wouldHaveCrashed);
	LLError::setDefaultLevel(LLError::LEVEL_ERROR);
		//< *TODO: should come from error config file. Note that we
		// have a command line option that sets this to debug.
	
#ifdef CTYPE_WORKAROUND
	ctype_workaround();
#endif

	ll_init_apr();
	apr_pool_t* pool = NULL;
	if(APR_SUCCESS != apr_pool_create(&pool, NULL))
	{
		std::cerr << "Unable to initialize pool" << std::endl;
		return 1;
	}
	apr_getopt_t* os = NULL;
	if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
	{
		std::cerr << "Unable to  pool" << std::endl;
		return 1;
	}

	// values used for controlling application
	bool verbose_mode = false;
	bool wait_at_exit = false;
	std::string test_group;

	// values use for options parsing
	apr_status_t apr_err;
	const char* opt_arg = NULL;
	int opt_id = 0;
	std::ofstream *output = NULL;
	const char *touch = NULL;
	
	while(true)
	{
		apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg);
		if(APR_STATUS_IS_EOF(apr_err)) break;
		if(apr_err)
		{
			char buf[255];		/* Flawfinder: ignore */
			std::cerr << "Error parsing options: "
					  << apr_strerror(apr_err, buf, 255) << std::endl;
			return 1;
		}
		switch (opt_id)
		{
		case 'g':
			test_group.assign(opt_arg);
			break;
		case 'h':
			stream_usage(std::cout, argv[0]);
			return 0;
			break;
		case 'l':
			stream_groups(std::cout, argv[0]);
			return 0;
		case 'v':
			verbose_mode = true;
			break;
		case 'o':
			output = new std::ofstream;
			output->open(opt_arg);
			break;
		case 's':	// --sourcedir
			tut::sSourceDir = opt_arg;
			// For convenience, so you can use tut::sSourceDir + "myfile"
			tut::sSourceDir += '/';
			break;
		case 't':
			touch = opt_arg;
			break;
		case 'w':
			wait_at_exit = true;
			break;
		case 'd':
			// *TODO: should come from error config file. We set it to
			// ERROR by default, so this allows full debug levels.
			LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
			break;
		default:
			stream_usage(std::cerr, argv[0]);
			return 1;
			break;
		}
	}

	// run the tests
	LLTestCallback callback(verbose_mode, output);
	tut::runner.get().set_callback(&callback);
	
	if(test_group.empty())
	{
		tut::runner.get().run_tests();
	}
	else
	{
		tut::runner.get().run_tests(test_group);
	}

	if (wait_at_exit)
	{
		std::cerr << "Waiting for input before exiting..." << std::endl;
		std::cin.get();
	}
	
	if (output)
	{
		output->close();
		delete output;
	}

	if (touch)
	{
		std::ofstream s;
		s.open(touch);
		s << "ok" << std::endl;
		s.close();
	}
	
	apr_terminate();
	return 0;
}