Ejemplo n.º 1
0
	qint64 NetworkDiskCache::expire ()
	{
		if (CurrentSize_ < 0)
		{
			collectGarbage ();
			return maximumCacheSize () * 8 / 10;
		}

		if (CurrentSize_ > maximumCacheSize ())
			collectGarbage ();

		return CurrentSize_;
	}
Ejemplo n.º 2
0
	void HistoryModel::loadData ()
	{
		collectGarbage ();

		if (const auto rc = rowCount ())
			removeRows (0, rc);

		Items_.clear ();
		Core::Instance ().GetStorageBackend ()->LoadHistory (Items_);

		QSet<QString> urls;
		for (auto i = Items_.begin (); i != Items_.end (); )
		{
			if (urls.contains (i->URL_))
				i = Items_.erase (i);
			else
			{
				urls << i->URL_;
				++i;
			}
		}

		const auto& now = QDateTime::currentDateTime ();
		for (const auto& item : Items_)
			Add (item, SectionNumber (item.DateTime_, now));
	}
Ejemplo n.º 3
0
void ScriptEngineServer::stop()
{
	try
	{
		_stopServer = true;
		GD::bl->threadManager.join(_mainThread);
		_out.printDebug("Debug: Waiting for script engine server's client threads to finish.");
		{
			std::lock_guard<std::mutex> stateGuard(_stateMutex);
			for(std::map<int32_t, std::shared_ptr<ClientData>>::iterator i = _clients.begin(); i != _clients.end(); ++i)
			{
				closeClientConnection(i->second);
			}
		}
		while(_clients.size() > 0)
		{
			collectGarbage();
			if(_clients.size() > 0) std::this_thread::sleep_for(std::chrono::milliseconds(100));
		}
		unlink(GD::socketPath.c_str());
	}
	catch(const std::exception& ex)
	{
		_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(BaseLib::Exception& ex)
	{
		_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(...)
	{
		_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
	}
}
Ejemplo n.º 4
0
bool ScriptEngine::scriptThreadMaxReached()
{
	try
	{
		_scriptThreadMutex.lock();
		if(_scriptThreads.size() >= GD::bl->settings.scriptThreadMax() * 100 / 125)
		{
			_scriptThreadMutex.unlock();
			collectGarbage();
			_scriptThreadMutex.lock();
			if(_scriptThreads.size() >= GD::bl->settings.scriptThreadMax())
			{
				_scriptThreadMutex.unlock();
				GD::out.printError("Error: Your script processing is too slow. More than " + std::to_string(GD::bl->settings.scriptThreadMax()) + " scripts are queued. Not executing script.");
				return true;
			}
		}
	}
	catch(const std::exception& ex)
	{
		GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(BaseLib::Exception& ex)
	{
		GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(...)
	{
		GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
	}
	_scriptThreadMutex.unlock();
	return false;
}
Ejemplo n.º 5
0
// - Purge players logging in if they have
//   not completed login in due time.
// - Purge players logging out
void CLounge::tick(long now)
{
  processLogins(now);
  processLogouts(now);

  if (now - lastGarbage_ > 1)
  {
    lastGarbage_ = now;
    collectGarbage();
  }
}
Ejemplo n.º 6
0
void ScriptEngine::dispose()
{
	if(_disposing) return;
	_disposing = true;
	while(_scriptThreads.size() > 0)
	{
		GD::out.printInfo("Info: Waiting for script threads to finish.");
		collectGarbage();
		if(_scriptThreads.size() > 0) std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	}
	php_homegear_shutdown();
}
Ejemplo n.º 7
0
void* wrenReallocate(WrenVM* vm, void* memory, size_t oldSize, size_t newSize)
{
#if WREN_DEBUG_TRACE_MEMORY
  printf("reallocate %p %ld -> %ld\n", memory, oldSize, newSize);
#endif

  // If new bytes are being allocated, add them to the total count. If objects
  // are being completely deallocated, we don't track that (since we don't
  // track the original size). Instead, that will be handled while marking
  // during the next GC.
  vm->bytesAllocated += newSize - oldSize;

#if WREN_DEBUG_GC_STRESS
  // Since collecting calls this function to free things, make sure we don't
  // recurse.
  if (newSize > 0) collectGarbage(vm);
#else
  if (vm->bytesAllocated > vm->nextGC) collectGarbage(vm);
#endif

  return vm->reallocate(memory, oldSize, newSize);
}
Ejemplo n.º 8
0
	NetworkDiskCache::NetworkDiskCache (const QString& subpath, QObject *parent)
	: QNetworkDiskCache (parent)
	, CurrentSize_ (-1)
	, InsertRemoveMutex_ (QMutex::Recursive)
	, GarbageCollectorWatcher_ (nullptr)
	{
		setCacheDirectory (GetUserDir (UserDir::Cache, "network/" + subpath).absolutePath ());
		auto timer = new QTimer (this);
		timer->setInterval (60 * 60 * 1000);
		connect (timer,
				SIGNAL (timeout ()),
				this,
				SLOT (collectGarbage ()));
	}
Ejemplo n.º 9
0
	HistoryModel::HistoryModel (QObject *parent)
	: QStandardItemModel { parent }
	{
		setHorizontalHeaderLabels ({tr ("Title"), tr ("URL"), tr ("Date") });
		QTimer::singleShot (0,
				this,
				SLOT (loadData ()));

		GarbageTimer_ = new QTimer (this);
		GarbageTimer_->start (15 * 60 * 1000);
		connect (GarbageTimer_,
				SIGNAL (timeout ()),
				this,
				SLOT (collectGarbage ()));
	}
Ejemplo n.º 10
0
Publisher::Subscriber::~Subscriber() {
  auto wlock = publisher_->state_.wlock();
  auto it = wlock->subscribers.begin();
  while (it != wlock->subscribers.end()) {
    auto sub = it->lock();
    // Prune vacated weak_ptr's or those that point to us
    if (!sub || sub.get() == this) {
      it = wlock->subscribers.erase(it);
    } else {
      ++it;
    }
  }
  // Take this opportunity to reap anything that is no longer
  // referenced now that we've removed some subscriber(s)
  wlock->collectGarbage();
}
Ejemplo n.º 11
0
bool Publisher::enqueue(json_ref&& payload) {
  std::vector<std::shared_ptr<Subscriber>> subscribers;

  {
    auto wlock = state_.wlock();

    // We need to collect live references for the notify portion,
    // but since we're holding the wlock, take this opportunity to
    // detect and prune dead subscribers and clean up some garbage.
    auto it = wlock->subscribers.begin();
    while (it != wlock->subscribers.end()) {
      auto sub = it->lock();
      // Prune vacated weak_ptr's
      if (!sub) {
        it = wlock->subscribers.erase(it);
      } else {
        ++it;
        // Remember that live reference so that we can notify
        // outside of the lock below.
        subscribers.emplace_back(std::move(sub));
      }
    }

    wlock->collectGarbage();

    if (subscribers.empty()) {
      return false;
    }

    auto item = std::make_shared<Item>();
    item->payload = std::move(payload);
    item->serial = wlock->nextSerial++;
    wlock->items.emplace_back(std::move(item));
  }

  // and notify them outside of the lock
  for (auto& sub : subscribers) {
    auto& n = sub->getNotify();
    if (n) {
      n();
    }
  }
  return true;
}
Ejemplo n.º 12
0
GameBoardPrivate::~GameBoardPrivate()
{
  // clean out the thing list
  while ( !thingList.empty() ) {
    ZZTThing::AbstractThing *thing = thingList.front();
    thingList.pop_front();
    delete thing;
  }

  collectGarbage();

  while ( !programs.empty() ) {
    ZZTOOP::Interpreter *prog = programs.front();
    programs.pop_front();
    delete prog;
  }

  self = 0;
}
Ejemplo n.º 13
0
void RequestManager::threadMethod() {
	while (!_killThread) {
		collectGarbage();
		EventMan.delay(100);
	}
}
Ejemplo n.º 14
0
void ScriptEngine::execute(const std::string path, const std::string arguments, std::shared_ptr<std::vector<char>> output, int32_t* exitCode, bool wait, int32_t threadId)
{
	try
	{
		if(_disposing)
		{
			setThreadNotRunning(threadId);
			return;
		}
		if(path.empty())
		{
			//No thread yet
			return;
		}
		if(!output) output.reset(new std::vector<char>());
		if(!wait)
		{
			collectGarbage();
			if(!scriptThreadMaxReached())
			{
				_scriptThreadMutex.lock();
				try
				{
					int32_t threadId = _currentScriptThreadID++;
					if(threadId == -1) threadId = _currentScriptThreadID++;
					_scriptThreads.insert(std::pair<int32_t, std::pair<std::thread, bool>>(threadId, std::pair<std::thread, bool>(std::thread(&ScriptEngine::execute, this, path, arguments, output, nullptr, true, threadId), true)));
				}
				catch(const std::exception& ex)
				{
					GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
				}
				catch(...)
				{
					GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
				}
				_scriptThreadMutex.unlock();
			}
			if(exitCode) *exitCode = 0;
			//No thread yet
			return;
		}
	}
	catch(const std::exception& ex)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
		setThreadNotRunning(threadId);
		return;
	}
	catch(BaseLib::Exception& ex)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
		setThreadNotRunning(threadId);
		return;
	}
	catch(...)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
		setThreadNotRunning(threadId);
		return;
	}
	if(exitCode) *exitCode = -1;
	if(!GD::bl->io.fileExists(path))
	{
		GD::out.printError("Error: PHP script \"" + path + "\" does not exist.");
		setThreadNotRunning(threadId);
		return;
	}
	ts_resource_ex(0, NULL); //Replaces TSRMLS_FETCH()
	try
	{
		zend_file_handle script;

		/* Set up a File Handle structure */
		script.type = ZEND_HANDLE_FILENAME;
		script.filename = path.c_str();
		script.opened_path = NULL;
		script.free_filename = 0;

		zend_homegear_globals* globals = php_homegear_get_globals();
		if(!globals)
		{
			ts_free_thread();
			setThreadNotRunning(threadId);
			return;
		}
		globals->output = output.get();
		globals->commandLine = true;
		globals->cookiesParsed = true;

		if(!tsrm_get_ls_cache() || !((sapi_globals_struct *) (*((void ***) tsrm_get_ls_cache()))[((sapi_globals_id)-1)]) || !((php_core_globals *) (*((void ***) tsrm_get_ls_cache()))[((core_globals_id)-1)]))
		{
			GD::out.printCritical("Critical: Error in PHP: No thread safe resource exists.");
			ts_free_thread();
			setThreadNotRunning(threadId);
			return;
		}
		PG(register_argc_argv) = 1;
		SG(server_context) = (void*)output.get(); //Must be defined! Otherwise php_homegear_activate is not called.
		SG(options) |= SAPI_OPTION_NO_CHDIR;
		SG(headers_sent) = 1;
		SG(request_info).no_headers = 1;
		SG(default_mimetype) = nullptr;
		SG(default_charset) = nullptr;
		SG(request_info).path_translated = estrndup(path.c_str(), path.size());

		if (php_request_startup(TSRMLS_C) == FAILURE) {
			GD::bl->out.printError("Error calling php_request_startup...");
			ts_free_thread();
			setThreadNotRunning(threadId);
			return;
		}

		std::vector<std::string> argv = getArgs(path, arguments);
		php_homegear_build_argv(argv);
		SG(request_info).argc = argv.size();
		SG(request_info).argv = (char**)malloc((argv.size() + 1) * sizeof(char*));
		for(uint32_t i = 0; i < argv.size(); ++i)
		{
			SG(request_info).argv[i] = (char*)argv[i].c_str(); //Value is not modified.
		}
		SG(request_info).argv[argv.size()] = nullptr;

		php_execute_script(&script);
		if(exitCode) *exitCode = EG(exit_status);

		php_request_shutdown(NULL);
		if(output->size() > 0)
		{
			std::string outputString(&output->at(0), output->size());
			if(BaseLib::HelperFunctions::trim(outputString).size() > 0) GD::out.printMessage("Script output:\n" + outputString);
		}
	}
	catch(const std::exception& ex)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(BaseLib::Exception& ex)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(...)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
	}
	if(SG(request_info).path_translated)
	{
		efree(SG(request_info).query_string);
		SG(request_info).query_string = nullptr;
	}
	if(SG(request_info).argv)
	{
		free(SG(request_info).argv);
		SG(request_info).argv = nullptr;
	}
	SG(request_info).argc = 0;
	ts_free_thread();
	setThreadNotRunning(threadId);
}
Ejemplo n.º 15
0
std::shared_ptr<BaseLib::FileDescriptor> ScriptEngineServer::getClientFileDescriptor()
{
	std::shared_ptr<BaseLib::FileDescriptor> descriptor;
	try
	{
		timeval timeout;
		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		fd_set readFileDescriptor;
		FD_ZERO(&readFileDescriptor);
		GD::bl->fileDescriptorManager.lock();
		int32_t nfds = _serverFileDescriptor->descriptor + 1;
		if(nfds <= 0)
		{
			GD::bl->fileDescriptorManager.unlock();
			_out.printError("Error: Socket descriptor is invalid.");
			return descriptor;
		}
		FD_SET(_serverFileDescriptor->descriptor, &readFileDescriptor);
		GD::bl->fileDescriptorManager.unlock();
		if(!select(nfds, &readFileDescriptor, NULL, NULL, &timeout))
		{
			if(GD::bl->hf.getTime() - _lastGargabeCollection > 60000 || _clients.size() > GD::bl->settings.scriptEngineServerMaxConnections() * 100 / 112) collectGarbage();
			return descriptor;
		}

		sockaddr_un clientAddress;
		socklen_t addressSize = sizeof(addressSize);
		descriptor = GD::bl->fileDescriptorManager.add(accept(_serverFileDescriptor->descriptor, (struct sockaddr *) &clientAddress, &addressSize));
		if(descriptor->descriptor == -1) return descriptor;
		_out.printInfo("Info: Connection accepted. Client number: " + std::to_string(descriptor->id));

		return descriptor;
	}
    catch(const std::exception& ex)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
    return descriptor;
}
Ejemplo n.º 16
0
void ScriptEngineServer::mainThread()
{
	try
	{
		getFileDescriptor(true); //Deletes an existing socket file
		std::shared_ptr<BaseLib::FileDescriptor> clientFileDescriptor;
		while(!_stopServer)
		{
			try
			{
				//Don't lock _stateMutex => no synchronisation needed
				if(_clients.size() > GD::bl->settings.scriptEngineServerMaxConnections())
				{
					collectGarbage();
					if(_clients.size() > GD::bl->settings.scriptEngineServerMaxConnections())
					{
						_out.printError("Error: There are too many clients connected to me. Waiting for connections to close. You can increase the number of allowed connections in main.conf.");
						std::this_thread::sleep_for(std::chrono::milliseconds(5000));
						continue;
					}
				}
				getFileDescriptor();
				if(!_serverFileDescriptor || _serverFileDescriptor->descriptor == -1)
				{
					std::this_thread::sleep_for(std::chrono::milliseconds(1000));
					continue;
				}
				clientFileDescriptor = getClientFileDescriptor();
				if(!clientFileDescriptor || clientFileDescriptor->descriptor == -1) continue;
			}
			catch(const std::exception& ex)
			{
				_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
				continue;
			}
			catch(BaseLib::Exception& ex)
			{
				_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
				continue;
			}
			catch(...)
			{
				_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
				continue;
			}
			try
			{
				std::shared_ptr<ClientData> clientData = std::shared_ptr<ClientData>(new ClientData(clientFileDescriptor));
				std::lock_guard<std::mutex> stateGuard(_stateMutex);
				clientData->id = _currentClientID++;
				_clients[clientData->id] = clientData;
				GD::bl->threadManager.start(clientData->readThread, true, &ScriptEngineServer::readClient, this, clientData);
			}
			catch(const std::exception& ex)
			{
				_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
			}
			catch(BaseLib::Exception& ex)
			{
				_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
			}
			catch(...)
			{
				_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
			}
		}
		GD::bl->fileDescriptorManager.close(_serverFileDescriptor);
	}
    catch(const std::exception& ex)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}