void close() noexcept { std::unique_lock< std::mutex > lk{ mtx_ }; closed_.store( true, std::memory_order_release); not_full_cnd_.notify_all(); not_empty_cnd_.notify_all(); }
std::shared_ptr<T> wait_pop() { std::unique_lock<std::mutex> lock(_mtx); _data_cond.wait(lock, [this]() { return _terminate || !_data.empty(); }); return _pop(); }
void push(T&& new_value) { std::lock_guard<std::mutex> lock(_mtx); _data.push(std::move(new_value)); _data_cond.notify_one(); }
void Signal(void) { (std::lock_guard<std::mutex>)m_lock, (m_shouldContinue = true), s_continueCond.notify_all(); }
void notify() { std::lock_guard<std::mutex> lock(_mtx); _data_cond.notify_all(); }
void cancelAbort() { std::unique_lock<std::mutex> lk(abortMutex); abortCondVar.notify_one(); }
void mainLoader(int, char*[], ServiceManager* services) { //dispatcher thread g_game.setGameState(GAME_STATE_STARTUP); srand(static_cast<unsigned int>(OTSYS_TIME())); #ifdef _WIN32 SetConsoleTitle(STATUS_SERVER_NAME); #endif std::cout << STATUS_SERVER_NAME << " - Version " << STATUS_SERVER_VERSION << std::endl; std::cout << "Compiled with " << BOOST_COMPILER << std::endl; std::cout << "Compiled on " << __DATE__ << ' ' << __TIME__ << " for platform "; #if defined(__amd64__) || defined(_M_X64) std::cout << "x64" << std::endl; #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) std::cout << "x86" << std::endl; #elif defined(__arm__) std::cout << "ARM" << std::endl; #else std::cout << "unknown" << std::endl; #endif std::cout << std::endl; std::cout << "A server developed by " << STATUS_SERVER_DEVELOPERS << std::endl; std::cout << "Visit our forum for updates, support, and resources: http://otland.net/." << std::endl; std::cout << std::endl; // read global config std::cout << ">> Loading config" << std::endl; if (!g_config.load()) { startupErrorMessage("Unable to load config.lua!"); return; } #ifdef _WIN32 const std::string& defaultPriority = g_config.getString(ConfigManager::DEFAULT_PRIORITY); if (strcasecmp(defaultPriority.c_str(), "high") == 0) { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } else if (strcasecmp(defaultPriority.c_str(), "above-normal") == 0) { SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); } #endif //set RSA key const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"); const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"); g_RSA.setKey(p, q); std::cout << ">> Establishing database connection..." << std::flush; Database* db = Database::getInstance(); if (!db->connect()) { startupErrorMessage("Failed to connect to database."); return; } std::cout << " MySQL " << Database::getClientVersion() << std::endl; // run database manager std::cout << ">> Running database manager" << std::endl; if (!DatabaseManager::isDatabaseSetup()) { startupErrorMessage("The database you have specified in config.lua is empty, please import the schema.sql to your database."); return; } g_databaseTasks.start(); DatabaseManager::updateDatabase(); if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !DatabaseManager::optimizeTables()) { std::cout << "> No tables were optimized." << std::endl; } //load vocations std::cout << ">> Loading vocations" << std::endl; if (!g_vocations.loadFromXml()) { startupErrorMessage("Unable to load vocations!"); return; } // load item data std::cout << ">> Loading items" << std::endl; if (Item::items.loadFromOtb("data/items/items.otb") != ERROR_NONE) { startupErrorMessage("Unable to load items (OTB)!"); return; } if (!Item::items.loadFromXml()) { startupErrorMessage("Unable to load items (XML)!"); return; } std::cout << ">> Loading script systems" << std::endl; if (!ScriptingManager::getInstance()->loadScriptSystems()) { startupErrorMessage("Failed to load script systems"); return; } std::cout << ">> Loading monsters" << std::endl; if (!g_monsters.loadFromXml()) { startupErrorMessage("Unable to load monsters!"); return; } std::cout << ">> Loading outfits" << std::endl; Outfits* outfits = Outfits::getInstance(); if (!outfits->loadFromXml()) { startupErrorMessage("Unable to load outfits!"); return; } std::cout << ">> Checking world type... " << std::flush; std::string worldType = asLowerCaseString(g_config.getString(ConfigManager::WORLD_TYPE)); if (worldType == "pvp") { g_game.setWorldType(WORLD_TYPE_PVP); } else if (worldType == "no-pvp") { g_game.setWorldType(WORLD_TYPE_NO_PVP); } else if (worldType == "pvp-enforced") { g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED); } else { std::cout << std::endl; std::ostringstream ss; ss << "> ERROR: Unknown world type: " << g_config.getString(ConfigManager::WORLD_TYPE) << ", valid world types are: pvp, no-pvp and pvp-enforced."; startupErrorMessage(ss.str()); return; } std::cout << asUpperCaseString(worldType) << std::endl; std::cout << ">> Loading map" << std::endl; if (!g_game.loadMainMap(g_config.getString(ConfigManager::MAP_NAME))) { startupErrorMessage("Failed to load map"); return; } std::cout << ">> Initializing gamestate" << std::endl; g_game.setGameState(GAME_STATE_INIT); // Game client protocols services->add<ProtocolGame>(g_config.getNumber(ConfigManager::GAME_PORT)); services->add<ProtocolLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); // OT protocols services->add<ProtocolStatus>(g_config.getNumber(ConfigManager::STATUS_PORT)); // Legacy login protocol services->add<ProtocolOld>(g_config.getNumber(ConfigManager::LOGIN_PORT)); RentPeriod_t rentPeriod; std::string strRentPeriod = asLowerCaseString(g_config.getString(ConfigManager::HOUSE_RENT_PERIOD)); if (strRentPeriod == "yearly") { rentPeriod = RENTPERIOD_YEARLY; } else if (strRentPeriod == "weekly") { rentPeriod = RENTPERIOD_WEEKLY; } else if (strRentPeriod == "monthly") { rentPeriod = RENTPERIOD_MONTHLY; } else if (strRentPeriod == "daily") { rentPeriod = RENTPERIOD_DAILY; } else { rentPeriod = RENTPERIOD_NEVER; } g_game.map.houses.payHouses(rentPeriod); IOMarket::checkExpiredOffers(); IOMarket::getInstance()->updateStatistics(); std::cout << ">> Loaded all modules, server starting up..." << std::endl; #ifndef _WIN32 if (getuid() == 0 || geteuid() == 0) { std::cout << "> Warning: " << STATUS_SERVER_NAME << " has been executed as root user, please consider running it as a normal user." << std::endl; } #endif g_game.start(services); g_game.setGameState(GAME_STATE_NORMAL); g_loaderSignal.notify_all(); }
void go() { std::unique_lock<std::mutex> lck(mtx); ready = true; cv.notify_all(); }
int up() { std::lock_guard<std::mutex> lock(mtx); if (++value > 0) cv.notify_one(); return value; }
/** * Wakes up the worker if it was sleeping because it didn't have anything * to do. */ inline void wakeUp() { _cv.notify_one(); }
void print_id(int id) { std::unique_lock<std::mutex> lck(mtx); while (!ready) cv.wait(lck); // ... std::cout << "thread " << id << '\n'; }
int main(int argc, char* argv[]) { ostringstream requestURI; requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=a.collection"; PlatformConfig config { OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos }; bool isRun = true; try { OCPlatform::Configure(config); string resourceTypeName = "a.collection"; OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource); //Non-intensive block until foundResource callback is called by OCPlatform //and onGet gets resource. //isResourceReady takes care of spurious wake-up std::unique_lock<std::mutex> lock(blocker); cv.wait(lock, isResourceReady); isReady = false; while (isRun) { int selectedMenu; cout << endl << "0 :: Quit 1 :: CREATE ACTIONSET 2 :: EXECUTE ACTION SET \n"; cout << "3 :: GET ACTIONSET 4 :: DELETE ACTIONSET \n" << endl; cin >> selectedMenu; OCRepresentation rep; string actionsetDesc; switch(selectedMenu) { case 0: isRun = false; break; case 1: actionsetDesc = buildActionSetDesc(); if(!actionsetDesc.empty()) { cout << "ActionSet :: " << actionsetDesc << endl; rep.setValue("ActionSet", actionsetDesc); } if (g_resource) { g_resource->put("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPut); } break; case 2: rep.setValue(DO_ACTION, std::string("allbulboff")); if (g_resource) { g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPost); } break; case 3: rep.setValue(GET_ACTIONSET, std::string("allbulboff")); if (g_resource) { g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPost); } break; case 4: rep.setValue("DelActionSet", std::string("allbulboff")); if (g_resource) { g_resource->put("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPut); } break; default: cout << "Invalid option" << endl; break; } fflush(stdin); } } catch (OCException& e) { cout << e.what() << endl; } return 0; }
void send(T && msg){ std::lock_guard<std::mutex> lck(_mutex); _Queue.push_back(msg); cond.notify_one(); }
namespace kernel { static std::thread sIpcThread; static std::atomic_bool sIpcThreadRunning; static std::mutex sIpcMutex; static std::condition_variable sIpcCond; static std::queue<IPCBuffer *> sIpcRequests; static std::queue<IPCBuffer *> sIpcResponses[3]; static void ipcThreadEntry(); /** * Start the IPC thread. */ void ipcStart() { std::unique_lock<std::mutex> lock { sIpcMutex }; sIpcThreadRunning.store(true); sIpcThread = std::thread { ipcThreadEntry }; } /** * Stop the IPC thread. */ void ipcShutdown() { std::unique_lock<std::mutex> lock { sIpcMutex }; if (sIpcThreadRunning.exchange(false)) { sIpcCond.notify_all(); lock.unlock(); sIpcThread.join(); } } /** * Submit an buffer to the IPC queue. */ void ipcDriverKernelSubmitRequest(IPCBuffer *buffer) { switch (cpu::this_core::id()) { case 0: buffer->cpuId = IOSCpuId::PPC0; break; case 1: buffer->cpuId = IOSCpuId::PPC1; break; case 2: buffer->cpuId = IOSCpuId::PPC2; break; default: decaf_abort("Unexpected core id"); } sIpcMutex.lock(); sIpcRequests.push(buffer); sIpcCond.notify_all(); sIpcMutex.unlock(); } /** * Handle PPC interrupt for when we have IPC responses to dispatch. */ void ipcDriverKernelHandleInterrupt() { auto driver = coreinit::internal::getIPCDriver(); auto &responses = sIpcResponses[driver->coreId]; // Copy respones to IPCDriver structure sIpcMutex.lock(); while (responses.size()) { driver->responses[driver->numResponses] = responses.front(); driver->numResponses++; responses.pop(); } sIpcMutex.unlock(); // Call userland IPCDriver callback coreinit::internal::ipcDriverProcessResponses(); } /** * Main thread entry point for the IPC thread. * * This thread represents the IOS side of the IPC mechanism. * * Responsible for receiving IPC requests and dispatching them to the * correct IOS device. */ void ipcThreadEntry() { std::unique_lock<std::mutex> lock { sIpcMutex }; while (true) { if (!sIpcRequests.empty()) { auto request = sIpcRequests.front(); sIpcRequests.pop(); lock.unlock(); iosDispatchIpcRequest(request); lock.lock(); switch (request->cpuId) { case IOSCpuId::PPC0: sIpcResponses[0].push(request); cpu::interrupt(0, cpu::IPC_INTERRUPT); break; case IOSCpuId::PPC1: sIpcResponses[1].push(request); cpu::interrupt(1, cpu::IPC_INTERRUPT); break; case IOSCpuId::PPC2: sIpcResponses[2].push(request); cpu::interrupt(2, cpu::IPC_INTERRUPT); break; default: decaf_abort("Unexpected cpu id"); } } if (!sIpcThreadRunning.load()) { break; } if (sIpcRequests.empty()) { sIpcCond.wait(lock); } } sIpcThreadRunning.store(false); } } // namespace kernel
void Signal(void) { std::lock_guard<std::mutex> lk(m_lock); m_signalled = true; m_condVar.notify_all(); }
int push(int n){ std::unique_lock<std::mutex> lck(mtx); Task.push(n); isEmpty.notify_all(); return 0; }
void Wait(void) { std::unique_lock<std::mutex> lk(m_lock); m_condVar.wait(lk, [this] {return this->m_signalled;}); }
void fiber_waiter::continuate(shared_state_basic * caller) noexcept { m_ready.store(true, std::memory_order_relaxed); m_thread_var.notify_all(); m_fiber_var.notify_all(); }
namespace glws { static char TAG[]="apitrace"; static JavaVM *s_javaVM = nullptr; static jobject s_activityObject = nullptr; static std::mutex s_activityObjectMutex; static jmethodID s_setSurfaceSizeMethodID = nullptr; static jfieldID s_descriptor = nullptr; typedef std::shared_ptr<ANativeWindow> AndroidWindow; static AndroidWindow s_currentNativeWindow; static std::atomic_int s_currentNativeWindowId(0); static std::mutex s_currentNativeWindowMutex; static int s_stdout_fd = -1; static int s_stderr_fd = -1; static std::mutex s_stateMutex; static std::condition_variable s_stateWait; static EGLDisplay eglDisplay = EGL_NO_DISPLAY; static char const *eglExtensions = NULL; static bool has_EGL_KHR_create_context = false; struct ResourceTracker; static std::mutex s_resourcesMutex; static std::vector<ResourceTracker*> s_resources; class FdWriter : public std::streambuf { public: FdWriter(int fd) { m_fd = fd; int opts = fcntl(m_fd, F_GETFL); opts = opts & (~O_NONBLOCK); fcntl(m_fd, F_SETFL, opts); } // basic_streambuf interface protected: std::streamsize xsputn(const char_type *__s, std::streamsize __n) { std::streamsize ret = 0; while( __n ) { ssize_t written = write(m_fd, __s, __n); if (written > 0) { __n -= written; __s += written; ret += written; } else { switch (errno) { case EBADF: case EINVAL: case EPIPE: std::exit(1); break; } } } return ret; } int_type overflow(int_type __c) { return xsputn(reinterpret_cast<const char_type *>(&__c), 1) == 1 ? __c : traits_type::eof(); } private: int m_fd = -1; }; static EGLenum translateAPI(glfeatures::Profile profile) { switch (profile.api) { case glfeatures::API_GL: return EGL_OPENGL_API; case glfeatures::API_GLES: return EGL_OPENGL_ES_API; default: assert(0); return EGL_NONE; } } /* Must be called before * * - eglCreateContext * - eglGetCurrentContext * - eglGetCurrentDisplay * - eglGetCurrentSurface * - eglMakeCurrent (when its ctx parameter is EGL_NO_CONTEXT ), * - eglWaitClient * - eglWaitNative */ static void bindAPI(EGLenum api) { if (eglBindAPI(api) != EGL_TRUE) { std::cerr << "error: eglBindAPI failed\n"; exit(1); } } struct EglVisual : public Visual { EglVisual(Profile prof) : Visual(prof) {} EGLConfig config = 0; EGLint format = -1; }; struct ResourceTracker { ResourceTracker() { s_resourcesMutex.lock(); s_resources.push_back(this); s_resourcesMutex.unlock(); } virtual ~ResourceTracker() { s_resourcesMutex.lock(); s_resources.erase(std::find(s_resources.begin(), s_resources.end(), this)); s_resourcesMutex.unlock(); } }; class EglDrawable : public Drawable, private ResourceTracker { public: EglDrawable(const Visual *vis, int w, int h, const pbuffer_info *info) : Drawable(vis, w, h, info), api(EGL_OPENGL_ES_API), windowId(0) { eglWaitNative(EGL_CORE_NATIVE_ENGINE); const EglVisual * eglVisual = static_cast<const EglVisual *>(visual); update(); ANativeWindow_setBuffersGeometry(window.get(), 0, 0, eglVisual->format); surface = eglCreateWindowSurface(eglDisplay, eglVisual->config, window.get(), NULL); } ~EglDrawable() { eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(eglDisplay, surface); eglWaitClient(); eglWaitNative(EGL_CORE_NATIVE_ENGINE); } void recreate(void) { EGLContext currentContext = eglGetCurrentContext(); EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW); EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ); bool rebindDrawSurface = currentDrawSurface == surface; bool rebindReadSurface = currentReadSurface == surface; if (rebindDrawSurface || rebindReadSurface) { eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(eglDisplay, surface); } const EglVisual * eglVisual = static_cast<const EglVisual *>(visual); ANativeWindow_setBuffersGeometry(window.get(), 0, 0, eglVisual->format); surface = eglCreateWindowSurface(eglDisplay, eglVisual->config, (EGLNativeWindowType)window.get(), NULL); if (rebindDrawSurface || rebindReadSurface) eglMakeCurrent(eglDisplay, surface, surface, currentContext); } void resize(int w, int h) { if (w == width && h == height) { return; } eglWaitClient(); Drawable::resize(w, h); resizeSurface(w, h); } void show(void) { if (visible) { return; } eglWaitClient(); eglWaitNative(EGL_CORE_NATIVE_ENGINE); Drawable::show(); } void swapBuffers(void) { if (update()) recreate(); bindAPI(api); eglSwapBuffers(eglDisplay, surface); } private: inline bool update() { if (windowId.load() == s_currentNativeWindowId.load()) return false; s_currentNativeWindowMutex.lock(); window = s_currentNativeWindow; windowId.store(s_currentNativeWindowId.load()); s_currentNativeWindowMutex.unlock(); return true; } void resizeSurface(int w, int h) { JNIEnv *env = nullptr; if (JNI_OK != s_javaVM->AttachCurrentThread(&env, nullptr)) { __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed"); std::exit(1); } s_activityObjectMutex.lock(); env->CallVoidMethod(s_activityObject, s_setSurfaceSizeMethodID, w, h); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } s_activityObjectMutex.unlock(); s_javaVM->DetachCurrentThread(); } public: EGLSurface surface; EGLenum api; private: AndroidWindow window; std::atomic_int windowId; }; class EglContext : public Context, private ResourceTracker { public: EGLContext context; EglContext(const Visual *vis, EGLContext ctx) : Context(vis), context(ctx) {} ~EglContext() { eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(eglDisplay, context); } }; void init(void) { eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (eglDisplay == EGL_NO_DISPLAY) { std::cerr << "error: unable to get EGL display\n"; exit(1); } EGLint major, minor; if (!eglInitialize(eglDisplay, &major, &minor)) { std::cerr << "error: unable to initialize EGL display\n"; exit(1); } eglExtensions = eglQueryString(eglDisplay, EGL_EXTENSIONS); has_EGL_KHR_create_context = checkExtension("EGL_KHR_create_context", eglExtensions); } void cleanup(void) { while (!s_resources.empty()) { delete *s_resources.rbegin(); } if (eglDisplay != EGL_NO_DISPLAY) { eglTerminate(eglDisplay); } eglDisplay = EGL_NO_DISPLAY; eglExtensions = nullptr; has_EGL_KHR_create_context = false; s_stateMutex.lock(); close(s_stdout_fd); close(s_stderr_fd); s_stdout_fd = -1; s_stderr_fd = -1; s_stateMutex.unlock(); } Visual * createVisual(bool doubleBuffer, unsigned samples, Profile profile) { EGLint api_bits; if (profile.api == glfeatures::API_GL) { api_bits = EGL_OPENGL_BIT; if (profile.core && !has_EGL_KHR_create_context) { return NULL; } } else if (profile.api == glfeatures::API_GLES) { switch (profile.major) { case 1: api_bits = EGL_OPENGL_ES_BIT; break; case 3: if (has_EGL_KHR_create_context) { api_bits = EGL_OPENGL_ES3_BIT; break; } /* fall-through */ case 2: api_bits = EGL_OPENGL_ES2_BIT; break; default: return NULL; } } else { assert(0); return NULL; } Attributes<EGLint> attribs; attribs.add(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); attribs.add(EGL_RED_SIZE, 1); attribs.add(EGL_GREEN_SIZE, 1); attribs.add(EGL_BLUE_SIZE, 1); attribs.add(EGL_ALPHA_SIZE, 1); attribs.add(EGL_DEPTH_SIZE, 1); attribs.add(EGL_STENCIL_SIZE, 1); attribs.add(EGL_RENDERABLE_TYPE, api_bits); attribs.end(EGL_NONE); EGLint num_configs = 0; if (!eglGetConfigs(eglDisplay, NULL, 0, &num_configs) || num_configs <= 0) { return NULL; } std::vector<EGLConfig> configs(num_configs); if (!eglChooseConfig(eglDisplay, attribs, &configs[0], num_configs, &num_configs) || num_configs <= 0) { return NULL; } // We can't tell what other APIs the trace will use afterwards, therefore // try to pick a config which supports the widest set of APIs. int bestScore = -1; EGLConfig config = configs[0]; for (EGLint i = 0; i < num_configs; ++i) { EGLint renderable_type = EGL_NONE; eglGetConfigAttrib(eglDisplay, configs[i], EGL_RENDERABLE_TYPE, &renderable_type); int score = 0; assert(renderable_type & api_bits); renderable_type &= ~api_bits; if (renderable_type & EGL_OPENGL_ES2_BIT) { score += 1 << 4; } if (renderable_type & EGL_OPENGL_ES3_BIT) { score += 1 << 3; } if (renderable_type & EGL_OPENGL_ES_BIT) { score += 1 << 2; } if (renderable_type & EGL_OPENGL_BIT) { score += 1 << 1; } if (score > bestScore) { config = configs[i]; bestScore = score; } } assert(bestScore >= 0); EGLint visual_id = -1; if (!eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &visual_id)) { assert(0); return NULL; } assert(visual_id != -1); EglVisual *visual = new EglVisual(profile); visual->config = config; visual->format = visual_id; return visual; } Drawable * createDrawable(const Visual *visual, int width, int height, const pbuffer_info *info) { return new EglDrawable(visual, width, height, info); } Context * createContext(const Visual *_visual, Context *shareContext, bool debug) { Profile profile = _visual->profile; const EglVisual *visual = static_cast<const EglVisual *>(_visual); EGLContext share_context = EGL_NO_CONTEXT; EGLContext context; Attributes<EGLint> attribs; if (shareContext) { share_context = static_cast<EglContext*>(shareContext)->context; } int contextFlags = 0; if (profile.api == glfeatures::API_GL) { if (has_EGL_KHR_create_context) { attribs.add(EGL_CONTEXT_MAJOR_VERSION_KHR, profile.major); attribs.add(EGL_CONTEXT_MINOR_VERSION_KHR, profile.minor); int profileMask = profile.core ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; attribs.add(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, profileMask); if (profile.forwardCompatible) { contextFlags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; } } else if (profile.versionGreaterOrEqual(3, 2)) { std::cerr << "error: EGL_KHR_create_context not supported\n"; return NULL; } } else if (profile.api == glfeatures::API_GLES) { if (has_EGL_KHR_create_context) { attribs.add(EGL_CONTEXT_MAJOR_VERSION_KHR, profile.major); attribs.add(EGL_CONTEXT_MINOR_VERSION_KHR, profile.minor); } else { attribs.add(EGL_CONTEXT_CLIENT_VERSION, profile.major); } } else { assert(0); return NULL; } if (debug) { contextFlags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; } if (contextFlags && has_EGL_KHR_create_context) { attribs.add(EGL_CONTEXT_FLAGS_KHR, contextFlags); } attribs.end(EGL_NONE); EGLenum api = translateAPI(profile); bindAPI(api); context = eglCreateContext(eglDisplay, visual->config, share_context, attribs); if (!context) { if (debug) { // XXX: Mesa has problems with EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR // with OpenGL ES contexts, so retry without it return createContext(_visual, shareContext, false); } return NULL; } return new EglContext(visual, context); } bool makeCurrentInternal(Drawable *drawable, Context *context) { if (!drawable || !context) { return eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } else { EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable); EglContext *eglContext = static_cast<EglContext *>(context); EGLBoolean ok; EGLenum api = translateAPI(eglContext->profile); bindAPI(api); ok = eglMakeCurrent(eglDisplay, eglDrawable->surface, eglDrawable->surface, eglContext->context); if (ok) { eglDrawable->api = api; } return ok; } } bool processEvents(void) { return false; } bool bindTexImage(Drawable *pBuffer, int iBuffer) { std::cerr << "error: EGL/Android::wglBindTexImageARB not implemented.\n"; assert(pBuffer->pbuffer); return true; } bool releaseTexImage(Drawable *pBuffer, int iBuffer) { std::cerr << "error: EGL/Android::wglReleaseTexImageARB not implemented.\n"; assert(pBuffer->pbuffer); return true; } bool setPbufferAttrib(Drawable *pBuffer, const int *attribList) { // nothing to do here. assert(pBuffer->pbuffer); return true; } static void readParamsAndStartTrace() { std::string paramsLine; char buff[4096]; while (true) { ssize_t sz = read(s_stdout_fd, buff, 4095); if (sz < 0) { cleanup(); return ; } buff[sz] = '\0'; paramsLine += buff; if (paramsLine.find('\n') > 0) break; } std::regex word_regex("(\"[^\"]*\")|([^\\s]+)"); auto words_begin = std::sregex_iterator(paramsLine.begin(), paramsLine.end(), word_regex); auto words_end = std::sregex_iterator(); std::vector<std::string> paramsVector; std::vector<char *> params; params.push_back(TAG); for (std::sregex_iterator i = words_begin; i != words_end; ++i) { paramsVector.push_back(i->str()); params.push_back(const_cast<char*>(paramsVector.back().c_str())); } { std::unique_lock<std::mutex> lock(s_stateMutex); __android_log_print(ANDROID_LOG_DEBUG, TAG, "Wait for stderr socket"); s_stateWait.wait(lock, []{return s_stderr_fd != -1; }); } __android_log_print(ANDROID_LOG_DEBUG, TAG, "Start retrace"); optind = 1; optreset = 1; main(params.size(), ¶ms[0]); cleanup(); // Remove "std::exit" after apitrace will cleanup its static variables. std::exit(0); // goodbye cruel world ! } static inline int getFd(JNIEnv* env, jobject obj) { return env->GetIntField(obj, s_descriptor); } static bool setFd(std::ostream &stream, int *state_fd, int fd) { std::lock_guard<std::mutex> lock(s_stateMutex); if (*state_fd != -1) return false; *state_fd = fd; delete dynamic_cast<FdWriter*>(stream.rdbuf(new FdWriter(fd))); return true; } static jboolean setStdoutFileDescriptor(JNIEnv *env, jobject /*object*/, jobject fd) { bool res = setFd(std::cout, &s_stdout_fd, getFd(env, fd)); if (res) std::async(std::launch::async, glws::readParamsAndStartTrace); return res; } static jboolean setStderrFileDescriptor(JNIEnv *env, jobject /*object*/, jobject fd) { bool res = setFd(std::cerr, &s_stderr_fd, getFd(env, fd)); if (res) s_stateWait.notify_one(); return res; } static void onActivityCreated(JNIEnv *env, jobject /*object*/, jobject activity) { s_activityObjectMutex.lock(); s_activityObject = env->NewGlobalRef(activity); s_activityObjectMutex.unlock(); } static void onSurfaceCreated(JNIEnv *env, jobject /*object*/, jobject surface) { s_currentNativeWindowMutex.lock(); s_currentNativeWindow = AndroidWindow(ANativeWindow_fromSurface(env, surface), [](ANativeWindow *w) { ANativeWindow_release(w); }); ++s_currentNativeWindowId; s_currentNativeWindowMutex.unlock(); } static void onSurfaceChanged(JNIEnv *env, jobject /*object*/, jobject surface, int /*format*/, int /*width*/, int /*height*/) { s_currentNativeWindowMutex.lock(); s_currentNativeWindow = AndroidWindow(ANativeWindow_fromSurface(env, surface), [](ANativeWindow *w) { ANativeWindow_release(w); }); ++s_currentNativeWindowId; s_currentNativeWindowMutex.unlock(); } static void onSurfaceRedrawNeeded(JNIEnv */*env*/, jobject /*object*/, jobject /*surface*/) { } static void onSurfaceDestroyed(JNIEnv */*env*/, jobject /*object*/) { s_currentNativeWindowMutex.lock(); s_currentNativeWindow.reset(); s_currentNativeWindowId.store(0); s_currentNativeWindowMutex.unlock(); } static void onActivityDestroyed(JNIEnv *env, jobject /*object*/) { s_activityObjectMutex.lock(); env->DeleteGlobalRef(s_activityObject); s_activityObject = nullptr; s_activityObjectMutex.unlock(); } static JNINativeMethod methods[] = { {"setStdoutFileDescriptor", "(Ljava/io/FileDescriptor;)Z", (void *)setStdoutFileDescriptor}, {"setStderrFileDescriptor", "(Ljava/io/FileDescriptor;)Z", (void *)setStderrFileDescriptor}, {"onActivityCreatedNative", "(Lapitrace/github/io/eglretrace/RetraceActivity;)V", (void *)onActivityCreated}, {"onSurfaceCreatedNative", "(Landroid/view/Surface;)V", (void *)onSurfaceCreated}, {"onSurfaceChangedNative", "(Landroid/view/Surface;III)V", (void *)onSurfaceChanged}, {"onSurfaceRedrawNeededNative", "(Landroid/view/Surface;)V", (void *)onSurfaceRedrawNeeded}, {"onSurfaceDestroyedNative", "()V", (void *)onSurfaceDestroyed}, {"onActivityDestroyedNative", "()V", (void *)onActivityDestroyed} }; } /* namespace glws */
namespace test { QString ErrMsg() { auto& errs = cpu::CpuMemory::Instance().DB40; errs.Read(); QString str_errs; // if (errs.sl1) // str_errs += "уровень масла в норме\n"; if (errs.sl2) str_errs += "пониженный уровень масла\n"; if (errs.sl3) str_errs += "аварийный уровень масла\n"; if (errs.sl4) str_errs += "верхний уровень перелив\n"; // if (errs.sl5) // str_errs += "нижний уровень перелив\n"; if (errs.sp1) str_errs += "фильтр всасывающий М1 загрязнен\n"; if (errs.sp2) str_errs += "фильтр всасывающий М2 загрязнен\n"; if (errs.sp3) str_errs += "фильтр всасывающий М3 загрязнен\n"; if (errs.sp4) str_errs += "фильтр всасывающий М3 загрязнен\n"; if (errs.sp5) str_errs += "фильтр всасывающий М4 загрязнен\n"; if (errs.sp6) str_errs += "фильтр всасывающий М5 загрязнен\n"; if (errs.sp7) str_errs += "фильтр тонкой очистки М1 загрязнен\n"; if (errs.sp8) str_errs += "фильтр грубой очистки М1 загрязнен\n"; if (errs.sp9) str_errs += "фильтр тонкой очистки М2 загрязнен\n"; if (errs.sp10) str_errs += "фильтр грубой очистки М2 загрязнен\n"; if (errs.sp11) str_errs += "фильтр тонкой очистки М4 загрязнен\n"; if (errs.sp12) str_errs += "фильтр грубой очистки М3 загрязнен\n"; if (errs.sp13) str_errs += "фильтр грубой очистки М3 загрязнен\n"; if (errs.sp14) str_errs += "фильтр контура охлаждения загрязнен\n"; if (errs.sp15) str_errs += "фильтр тонкой очистки М12 загрязнен\n"; if (errs.sq1) str_errs += "кран М1 закрыт\n"; if (errs.sq3) str_errs += "кран М2 закрыт\n"; if (errs.sq5) str_errs += "кран М3 закрыт\n"; if (errs.sq7) str_errs += "кран М3 закрыт\n"; if (errs.sq9) str_errs += "кран М4 закрыт\n"; if (errs.sq11) str_errs += "кран М5 закрыт\n"; if (errs.sq13) str_errs += "кран дренажа М1 закрыт\n"; if (errs.sq14) str_errs += "кран дренажа М2 закрыт\n"; if (errs.sq15) str_errs += "кран дренажа М4 закрыт\n"; if (errs.fault_m1) str_errs += "нет включения М1\n"; if (errs.fault_m2) str_errs += "нет включения М2\n"; if (errs.fault_m3) str_errs += "нет включения М3\n"; if (errs.fault_m4) str_errs += "нет включения М4\n"; if (errs.fault_m5) str_errs += "нет включения М5\n"; if (errs.fault_m6) str_errs += "нет включения М6\n"; if (errs.fault_m8) str_errs += "нет включения М8\n"; if (errs.fault_m10) str_errs += "нет включения М10\n"; if (errs.fault_m12) str_errs += "нет включения М12\n"; if (errs.fault_phasing) str_errs += "не правильная фазировка\n"; if (errs.p_no) str_errs += "давление в системе не установилось\n"; if (errs.p_upr_no) str_errs += "давление в канале Х не установилось\n"; if (errs.q_no) str_errs += "расход не установился\n"; if (errs.v_no) str_errs += "Напряжение не в допуске\n"; if (errs.fault_p_op12) str_errs += "Аварийное давление\n"; if (errs.fault_p_op22) str_errs += "Аварийное давление\n"; return str_errs; } std::condition_variable CondVar; TestCommonData::TestCommonData( TestCase* test_case, QString const& name, uint8_t number, uint8_t id ): test::Test( test_case, name, number, id ), OilTemp(0), mCommand( cpu::CpuMemory::Instance().DB31 ) {} QJsonObject TestCommonData::Serialise() const { QJsonObject obj; obj.insert("OilTemp", OilTemp ); obj.insert("TestingTime", TestingTime ); return obj; } bool TestCommonData::Deserialize( QJsonObject const& obj ) { OilTemp = obj.value("OilTemp").toDouble(); TestingTime = obj.value("TestingTime").toInt(); return true; } uint8_t TestCommonData::CommandID() { return mId; } void TestCommonData::Start() { mCommand.N_Operation = CommandID(); mCommand.Start_Oper = true; mCommand.Stop_Oper = false; mCommand.Nasos_M2 = app::Settings::Instance().MainPupm() == "M2"; mCommand.OP15_25_Continum = false; mCommand.Next_Amp = false; mCommand.Write(); StartTime.start(); } void TestCommonData::Wait( bool& work, bool& done) { work = false; done = false; bool started = false; while( !done || !started ) { if (work) started = true; UpdateData(); if ( IsStopped() ) { mCommand.Start_Oper = false; mCommand.Stop_Oper = true; mCommand.Nasos_M2 = app::Settings::Instance().MainPupm() == "M2"; mCommand.OP15_25_Continum = false; mCommand.Next_Amp = false; mCommand.Write(); Log( "Испытание прервано" ); return; } } TestingTime = StartTime.elapsed()/1000; *mStopMarker = !CheckErrors(); } bool TestCommonData::CheckErrors() { // Exceptions.Read(); auto& mem = cpu::CpuMemory::Instance().M1; QString str_errs = ErrMsg(); if ( str_errs.isEmpty() ) return true; std::mutex mutex; std::unique_lock< std::mutex > lock( mutex ); Launcher( std::bind( &TestCommonData::ShowErrors, this, str_errs ) ); CondVar.wait( lock ); mem.SetKvitir_Osch( true ); return false; } void TestCommonData::ShowErrors( QString const& err ) { QMessageBox msg; msg.setWindowTitle( "Ошибки тестирования" ); msg.setText( err.left(200) + "..." ); msg.addButton( QMessageBox::Ok ); msg.setModal( true ); msg.exec(); CondVar.notify_one(); } namespace hydro { uint8_t Test::mTestsCount = 1; Test::Test( QString const& name, uint8_t id ): test::TestCommonData( &HydroTests, name, mTestsCount, id ), mResults( cpu::CpuMemory::Instance().DB32 ) { ++mTestsCount; } void Test::UpdateData() { mResults.Read(); } }//namespace hydro namespace servo { uint8_t Test::mTestsCount = 1; Test::Test( QString const& name, uint8_t id_board, uint8_t id_reel ): test::TestCommonData( &ServoTests, name, mTestsCount, id_board ), mTemperature( cpu::CpuMemory::Instance().DB32 ), mControlBoardBits( cpu::CpuMemory::Instance().DB34 ), mControlReelBits( cpu::CpuMemory::Instance().DB36 ), m11Results( cpu::CpuMemory::Instance().DB2 ), m12Results( cpu::CpuMemory::Instance().DB3 ), m13Results( cpu::CpuMemory::Instance().DB9 ), m14Result1( cpu::CpuMemory::Instance().DB10 ), m14Result2( cpu::CpuMemory::Instance().DB23 ), m15Result( cpu::CpuMemory::Instance().DB11 ), m1525Counts( cpu::CpuMemory::Instance().DB60 ), mIdReel( id_reel ) { ++mTestsCount; } void Test::UpdateData() { if (ReelControl()) mControlReelBits.Read(); else mControlBoardBits.Read(); mTemperature.Read(); } uint8_t Test::CommandID() { return ReelControl() ? mIdReel : mId; } bool Test::ReelControl() const { return test::servo::Parameters::Instance().ReelControl() == RC_REEL; } }//namespace servo namespace control_board { uint8_t Test::mTestsCount = 1; Test::Test( QString const& name, uint8_t id ): test::TestCommonData( &ControlBoardTests, name, mTestsCount, id ), mBits( cpu::CpuMemory::Instance().DB39 ), mTemperature( cpu::CpuMemory::Instance().DB32 ), m31Results( cpu::CpuMemory::Instance().DB22 ) { ++mTestsCount; } void Test::UpdateData() { mBits.Read(); mTemperature.Read(); } }//namespace control_board namespace hydro_cylinder { uint8_t Test::mTestsCount = 1; Test::Test( QString const& name, uint8_t id ): test::TestCommonData( &HydroCylinder, name, mTestsCount, id ), mBits( cpu::CpuMemory::Instance().DB39 ), mTemperature( cpu::CpuMemory::Instance().DB32 ) { ++mTestsCount; } void Test::UpdateData() { mBits.Read(); mTemperature.Read(); } }//namespace hydro_cylinder }//namespace test
void startupErrorMessage(const std::string& errorStr) { std::cout << "> ERROR: " << errorStr << std::endl; g_loaderSignal.notify_all(); }
virtual void updated() { std::cout << __FUNCTION__ << "Wallet updated"; update_triggered = true; cv_update.notify_one(); }
void Delay(void) { std::unique_lock<std::mutex> lk(m_lock); s_continueCond.wait(lk, [this] () {return m_shouldContinue;}); }
virtual void refreshed() { std::cout << __FUNCTION__ << "Wallet refreshed"; refresh_triggered = true; cv_refresh.notify_one(); }
void notify_and_terminate() { std::lock_guard<std::mutex> lock(_mtx); _terminate = true; _data_cond.notify_all(); }
void put(const T &val) { std::unique_lock<std::mutex> lock(buffer_access); space_available.wait(lock, [this]{ return !full(); }); buf[p++] = val; p %= buf.size(); data_available.notify_one(); }
void push(const T& new_value) { std::lock_guard<std::mutex> lock(_mtx); _data.push(new_value); _data_cond.notify_one(); }
void get(T &val) { std::unique_lock<std::mutex> lock(buffer_access); data_available.wait(lock, [this]{ return !empty(); }); val = buf[g++]; g %= buf.size(); space_available.notify_one(); }
bool wait_pop(T& value) { std::unique_lock<std::mutex> lock(_mtx); _data_cond.wait(lock, [this]() { return _terminate || !_data.empty(); }); return _pop(value); }
void wait() { std::unique_lock<std::mutex> locker(mtx); cv.wait(locker, [this]{return counter>0;}); counter--; }