Ejemplo n.º 1
0
//virtual
bool LLTextureCacheWorker::doWork(S32 param)
{
	//allocate a new local apr_pool
	LLAPRPool pool ;

	//save the current mFileAPRPool to avoid breaking anything.
	apr_pool_t* old_pool = mCache->getFileAPRPool() ;
	//make mFileAPRPool to point to the local one
	mCache->setFileAPRPool(pool.getAPRPool()) ;

	bool res = false;
	if (param == 0) // read
	{
		res = doRead();
	}
	else if (param == 1) // write
	{
		res = doWrite();
	}
	else
	{
		llassert_always(0);
	}

	//set mFileAPRPool back, the local one will be released automatically.
	mCache->setFileAPRPool(old_pool) ;

	return res;
}
Ejemplo n.º 2
0
// Added to mitigate the effect of libcurl looking
// for the ALL_PROXY and http_proxy env variables
// and deciding to insert a Pragma: no-cache
// header! The only usage of this method at the
// time of this writing is in llhttpclient.cpp
// in the request() method, where this method
// is called with use_proxy = FALSE
void LLURLRequest::useProxy(bool use_proxy)
{
    static char *env_proxy;

    if (use_proxy && (env_proxy == NULL))
    {
        apr_status_t status;
        LLAPRPool pool;
		status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
        if (status != APR_SUCCESS)
        {
			status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
        }
        if (status != APR_SUCCESS)
        {
           use_proxy = FALSE;
        }
    }


    lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;

    if (env_proxy && use_proxy)
    {
		mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
    }
    else
    {
        mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, "");
    }
}
Ejemplo n.º 3
0
static void initialize() {
	static bool initialized = false;	
	if (!initialized) {
		apr_dso_handle_t* hprog = 0;
		LLAPRPool pool;
		pool.create();
#if LL_WINDOWS
		apr_dso_load(&hprog, "libtcmalloc_minimal.dll", pool());
#else
		apr_dso_load(&hprog, 0, pool());
#endif
		apr_dso_sym((apr_dso_handle_sym_t*)&MallocExtension_GetNumericProperty,
			hprog, "MallocExtension_GetNumericProperty");
		apr_dso_sym((apr_dso_handle_sym_t*)&MallocExtension_GetStats,
			hprog, "MallocExtension_GetStats");
		initialized = true;
	}	
}
void ungrab_dbus_syms()
{ 
	// should be safe to call regardless of whether we've
	// actually grabbed syms.

	if ( sSymDBUSDSOHandleG )
	{
		apr_dso_unload(sSymDBUSDSOHandleG);
		sSymDBUSDSOHandleG = NULL;
	}

	sSymDBUSDSOMemoryPool.destroy();

	// NULL-out all of the symbols we'd grabbed
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0)
#include "llappviewerlinux_api_dbus_syms_raw.inc"
#undef LL_DBUS_SYM

	sSymsGrabbed = false;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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

	LLAPRPool pool;
	pool.create();
	apr_getopt_t* os = NULL;
	if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv))
	{
		std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << 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();
	}
	
	return 0;
}
bool grab_dbus_syms(std::string dbus_dso_name)
{
	if (sSymsGrabbed)
	{
		// already have grabbed good syms
		return TRUE;
	}

	bool sym_error = false;
	bool rtn = false;
	apr_status_t rv;
	apr_dso_handle_t *sSymDBUSDSOHandle = NULL;

#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0)

	//attempt to load the shared library
	sSymDBUSDSOMemoryPool.create();
  
#ifdef LL_STANDALONE
    void *dso_handle = dlopen(dbus_dso_name.c_str(), RTLD_NOW | RTLD_GLOBAL);
    rv = (!dso_handle)?APR_EDSOOPEN:apr_os_dso_handle_put(&sSymDBUSDSOHandle,
            dso_handle, sSymDBUSDSOMemoryPool());

	if ( APR_SUCCESS == rv )
#else
	if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle,
					       dbus_dso_name.c_str(),
					       sSymDBUSDSOMemoryPool()) ))
#endif
	{
		INFOMSG("Found DSO: %s", dbus_dso_name.c_str());

#include "llappviewerlinux_api_dbus_syms_raw.inc"
      
		if ( sSymDBUSDSOHandle )
		{
			sSymDBUSDSOHandleG = sSymDBUSDSOHandle;
			sSymDBUSDSOHandle = NULL;
		}
      
		rtn = !sym_error;
	}
	else
	{
		INFOMSG("Couldn't load DSO: %s", dbus_dso_name.c_str());
		rtn = false; // failure
	}

	if (sym_error)
	{
		WARNMSG("Failed to find necessary symbols in DBUS-GLIB libraries.");
	}
#undef LL_DBUS_SYM

	sSymsGrabbed = rtn;
	if (!sSymsGrabbed)
	{
		sSymDBUSDSOMemoryPool.destroy();
	}
	return rtn;
}
Ejemplo n.º 8
0
int LLProcessLauncher::launch(void)
{
	// If there was already a process associated with this object, kill it.
	kill();
	orphan();
	
	int result = 0;
	int current_wd = -1;
	
	// create an argv vector for the child process
	const char ** fake_argv = new const char *[mLaunchArguments.size() + 2];  // 1 for the executable path, 1 for the NULL terminator

	int i = 0;
	
	// add the executable path
	fake_argv[i++] = mExecutable.c_str();
	
	// and any arguments
	for(int j=0; j < mLaunchArguments.size(); j++)
		fake_argv[i++] = mLaunchArguments[j].c_str();
	
	// terminate with a null pointer
	fake_argv[i] = NULL;
	
	if(!mWorkingDir.empty())
	{
		// save the current working directory
		current_wd = ::open(".", O_RDONLY);
	
		// and change to the one the child will be executed in
		if (::chdir(mWorkingDir.c_str()))
		{
			// chdir failed
		}
	}
		
	pid_t id;
	{
#ifdef DEBUG_PIPE_CHILD_ERROR_REPORTING
		// Set up a pipe to the child process for error reporting.
		apr_file_t* in;
		apr_file_t* out;
		LLAPRPool pool;
		pool.create();
#if(APR_VERSION_MAJOR==1 && APR_VERSION_MINOR>=3 || APR_VERSION_MAJOR>1)
		apr_status_t status = apr_file_pipe_create_ex(&in, &out, APR_FULL_BLOCK, pool());
#else
		apr_status_t status = apr_file_pipe_create(&in, &out, pool());
#endif
		assert(status == APR_SUCCESS);
		bool success = (status == APR_SUCCESS);
		if (success)
		{
			apr_interval_time_t const timeout = 10000000;	// 10 seconds.
			status = apr_file_pipe_timeout_set(in, timeout);
			assert(status == APR_SUCCESS);
			success = (status == APR_SUCCESS);
		}
#endif // DEBUG_PIPE_CHILD_ERROR_REPORTING

		// flush all buffers before the child inherits them
		::fflush(NULL);

		id = vfork();
		if (id == 0)
		{
			// child process

#ifdef DEBUG_PIPE_CHILD_ERROR_REPORTING
			// Tell parent process we're about to call execv.
			write_pipe(out, "CALLING EXECV");
#ifdef _DEBUG
			char const* display = getenv("DISPLAY");
			std::cerr << "Calling ::execv(\"" << mExecutable << '"';
			for(int j = 0; j < i; ++j)
              std::cerr << ", \"" << fake_argv[j] << '"';
			std::cerr << ") with DISPLAY=\"" << (display ? display : "NULL") << '"' << std::endl;
#endif
#endif // DEBUG_PIPE_CHILD_ERROR_REPORTING

			::execv(mExecutable.c_str(), (char * const *)fake_argv);

#ifdef DEBUG_PIPE_CHILD_ERROR_REPORTING
			status = APR_FROM_OS_ERROR(apr_get_os_error());
			char message[256];
			char errbuf[128];
			apr_strerror(status, errbuf, sizeof(errbuf));
			snprintf(message, sizeof(message), "Child process: execv: %s: %s", mExecutable.c_str(), errbuf);
			write_pipe(out, message);
#ifdef _DEBUG
			std::cerr << "::execv() failed." << std::endl;
#endif
#endif // DEBUG_PIPE_CHILD_ERROR_REPORTING

			// If we reach this point, the exec failed.
			// Use _exit() instead of exit() per the vfork man page.
			_exit(0);
		}

		// parent process

#ifdef DEBUG_PIPE_CHILD_ERROR_REPORTING
		// Close unused pipe end.
		apr_file_close(out);

		if (success)
		{
			// Attempt to do error reporting.
			std::string message = read_pipe(in);
			success = (message == "CALLING EXECV");
			assert(success);
			if (success)
			{
				status = apr_file_pipe_timeout_set(in, 2000000);	// Only wait 2 seconds.
				message = read_pipe(in, true);
				if (message != "TIMEOUT" && message != "END OF FILE")
				{
					// Most likely execv failed.
					llwarns << message << llendl;
					assert(false);	// Fail in debug mode.
				}
			}
		}

		// Clean up.
		apr_file_close(in);
#endif // DEBUG_PIPE_CHILD_ERROR_REPORTING

	}

	if(current_wd >= 0)
	{
		// restore the previous working directory
		if (::fchdir(current_wd))
		{
			// chdir failed
		}
		::close(current_wd);
	}
	
	delete[] fake_argv;
	
	mProcessID = id;
	
	// At this point, the child process will have been created (since that's how vfork works -- the child borrowed our execution context until it forked)
	// If the process doesn't exist at this point, the exec failed.
	if(!isRunning())
	{
		result = -1;
	}
	
	return result;
}