bool XzeroDaemon::setup(std::unique_ptr<std::istream>&& settings, const std::string& filename, int optimizationLevel) { TRACE(1, "setup(%s)", filename.c_str()); FlowParser parser(this); parser.importHandler = std::bind(&XzeroDaemon::import, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); if (!parser.open(filename, std::move(settings))) { sd_notifyf(0, "ERRNO=%d", errno); fprintf(stderr, "Failed to open file: %s\n", filename.c_str()); return false; } unit_ = parser.parse(); if (!unit_) return false; if (dumpAST_) ASTPrinter::print(unit_.get()); std::unique_ptr<IRProgram> ir = IRGenerator::generate(unit_.get()); if (!ir) { fprintf(stderr, "IR generation failed. Aborting.\n"); return false; } { PassManager pm; // mandatory passes pm.registerPass(std::make_unique<UnusedBlockPass>()); // optional passes if (optimizationLevel >= 1) { pm.registerPass(std::make_unique<EmptyBlockElimination>()); pm.registerPass(std::make_unique<InstructionElimination>()); } pm.run(ir.get()); } if (dumpIR_) { ir->dump(); } program_ = TargetCodeGenerator().generate(ir.get()); ir.reset(); if (!program_) { fprintf(stderr, "Code generation failed. Aborting.\n"); return false; } if (!program_->link(this)) { fprintf(stderr, "Program linking failed. Aborting.\n"); return false; } if (!validateConfig()) { return false; } if (dumpTargetCode_) program_->dump(); // run setup TRACE(1, "run 'setup'"); if (program_->findHandler("setup")->run(nullptr)) // should not return true return false; // grap the request handler TRACE(1, "get pointer to 'main'"); { auto main = program_->findHandler("main"); server_->requestHandler = [=](x0::HttpRequest* r) { FlowVM::Runner* cx = static_cast<FlowVM::Runner*>(r->setCustomData(r, main->createRunner())); cx->setUserData(r); bool handled = cx->run(); if (!cx->isSuspended() && !handled) { r->finish(); } }; } // {{{ setup server-tag { #if defined(HAVE_SYS_UTSNAME_H) { utsname utsname; if (uname(&utsname) == 0) { addComponent(std::string(utsname.sysname) + "/" + utsname.release); addComponent(utsname.machine); } } #endif #if defined(HAVE_BZLIB_H) { std::string zver("bzip2/"); zver += BZ2_bzlibVersion(); zver = zver.substr(0, zver.find(",")); addComponent(zver); } #endif #if defined(HAVE_ZLIB_H) { std::string zver("zlib/"); zver += zlib_version; addComponent(zver); } #endif Buffer tagbuf; tagbuf.push_back("x0/" VERSION); if (!components_.empty()) { tagbuf.push_back(" ("); for (int i = 0, e = components_.size(); i != e; ++i) { if (i) tagbuf.push_back(", "); tagbuf.push_back(components_[i]); } tagbuf.push_back(")"); } server_->tag = tagbuf.str(); } // }}} // {{{ run post-config hooks TRACE(1, "setup: post_config"); for (auto i: plugins_) if (!i->post_config()) goto err; // }}} // {{{ run post-check hooks TRACE(1, "setup: post_check"); for (auto i: plugins_) if (!i->post_check()) goto err; // }}} // {{{ check for available TCP listeners if (server_->listeners().empty()) { log(Severity::error, "No HTTP listeners defined"); goto err; } for (auto i: server_->listeners()) if (!i->isOpen()) goto err; // }}} // {{{ check for SO_REUSEPORT feature in TCP listeners if (server_->workers().size() == 1) { // fast-path scheduling for single-threaded mode server_->workers().front()->bind(server_->listeners().front()); } else { std::list<ServerSocket*> dups; for (auto listener: server_->listeners()) { if (listener->reusePort()) { for (auto worker: server_->workers()) { if (worker->id() > 0) { // clone listener for non-main worker listener = listener->clone(worker->loop()); dups.push_back(listener); } worker->bind(listener); } } } // FIXME: this is not yet well thought. // - how to handle configuration file reloads wrt SO_REUSEPORT? for (auto dup: dups) { server_->listeners().push_back(dup); } } // }}} // {{{ x0d: check for superfluous passed file descriptors (and close them) for (auto fd: ServerSocket::getInheritedSocketList()) { bool found = false; for (auto li: server_->listeners()) { if (fd == li->handle()) { found = true; break; } } if (!found) { log(Severity::debug, "Closing inherited superfluous listening socket %d.", fd); ::close(fd); } } // }}} // {{{ systemd: check for superfluous passed file descriptors if (int count = sd_listen_fds(0)) { int maxfd = SD_LISTEN_FDS_START + count; count = 0; for (int fd = SD_LISTEN_FDS_START; fd < maxfd; ++fd) { bool found = false; for (auto li: server_->listeners()) { if (fd == li->handle()) { found = true; break; } } if (!found) { ++count; } } if (count) { fprintf(stderr, "superfluous systemd file descriptors: %d\n", count); return false; } } // }}} // XXX post worker wakeup // we do an explicit wakeup of all workers here since there might be already // some (configure-time related) events pending, i.e. director's (fcgi) health checker // FIXME this is more a workaround than a fix. for (auto worker: server_->workers()) worker->wakeup(); TRACE(1, "setup: done."); return true; err: return false; }
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); try { // Get the requested client version (default is 1) and check it is 2 or 3. EGLint client_version = 1; bool reset_notification = false; bool robust_access = false; if (attrib_list) { for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2) { switch (attribute[0]) { case EGL_CONTEXT_CLIENT_VERSION: client_version = attribute[1]; break; case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: if (attribute[1] == EGL_TRUE) { return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented // robust_access = true; } else if (attribute[1] != EGL_FALSE) return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); break; case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT) reset_notification = true; else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT) return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); break; default: return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); } } } if (client_version != 2 && client_version != 3) { return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); } egl::Display *display = static_cast<egl::Display*>(dpy); if (share_context) { gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context); if (sharedGLContext->isResetNotificationEnabled() != reset_notification) { return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT); } if (sharedGLContext->getClientVersion() != client_version) { return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT); } // Can not share contexts between displays if (sharedGLContext->getRenderer() != display->getRenderer()) { return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT); } } if (!validateConfig(display, config)) { return EGL_NO_CONTEXT; } return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access); } catch (...) { return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } }