qint64 NetworkDiskCache::expire () { if (CurrentSize_ < 0) { collectGarbage (); return maximumCacheSize () * 8 / 10; } if (CurrentSize_ > maximumCacheSize ()) collectGarbage (); return CurrentSize_; }
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)); }
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__); } }
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; }
// - 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(); } }
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(); }
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); }
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 ())); }
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 ())); }
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(); }
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; }
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; }
void RequestManager::threadMethod() { while (!_killThread) { collectGarbage(); EventMan.delay(100); } }
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); }
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; }
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__); } }