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();
 }
Example #6
0
void cancelAbort() {
  std::unique_lock<std::mutex> lk(abortMutex);
  abortCondVar.notify_one();
}
Example #7
0
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();
}
Example #8
0
void go() {
	std::unique_lock<std::mutex> lck(mtx);
	ready = true;
	cv.notify_all();
}
Example #9
0
 int up() {
     std::lock_guard<std::mutex> lock(mtx);
     if (++value > 0)
         cv.notify_one();
     return value;
 }
Example #10
0
 /**
  * Wakes up the worker if it was sleeping because it didn't have anything
  * to do.
  */
 inline void wakeUp() {
     _cv.notify_one();
 }
Example #11
0
void print_id(int id) {
	std::unique_lock<std::mutex> lck(mtx);
	while (!ready) cv.wait(lck);
	// ...
	std::cout << "thread " << id << '\n';
}
Example #12
0
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;
}
Example #13
0
 void send(T && msg){
     std::lock_guard<std::mutex> lck(_mutex);
     _Queue.push_back(msg);
     cond.notify_one();
 }
Example #14
0
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
Example #15
0
 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;
 }
Example #17
0
 void Wait(void) {
   std::unique_lock<std::mutex> lk(m_lock);
   m_condVar.wait(lk, [this] {return this->m_signalled;});
 }
Example #18
0
	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(), &params[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 */
Example #20
0
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
Example #21
0
void startupErrorMessage(const std::string& errorStr)
{
    std::cout << "> ERROR: " << errorStr << std::endl;
    g_loaderSignal.notify_all();
}
Example #22
0
 virtual void updated()
 {
     std::cout << __FUNCTION__ << "Wallet updated";
     update_triggered = true;
     cv_update.notify_one();
 }
Example #23
0
 void Delay(void) {
   std::unique_lock<std::mutex> lk(m_lock);
   s_continueCond.wait(lk, [this] () {return m_shouldContinue;});
 }
Example #24
0
 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();
 }
Example #26
0
 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();
 }
Example #28
0
 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--;
	}