28 static volatile bool Waiting_;
29 static std::vector<pollfd> Fdlist_;
30 static std::map<int, FdHandler> Handlers_;
31 static Waiter::AppInfo AppInfo_;
33 void Waiter::OnPrepared()
35 if (!context.Prepare())
37 _DBG("Fail to Prepare...");
41 void Waiter::OnRequested(const AppInfo& info)
43 // do some job on user id is still system
45 if (!context.Request())
47 _DBG("Fail to Request...");
51 void Waiter::OnExecuted(const char *path, const char *app_root, int argc, char *argv[])
53 if (!context.Execute(path, app_root, argc, argv))
55 _DBG("Fail to Execute...");
59 void Waiter::OnWaiting()
64 _DBG("start polling...");
67 if (poll(Fdlist_.data(), Fdlist_.size(), -1) < 0)
70 for (auto &p : Fdlist_)
72 if ( (p.revents | POLLIN) != 0 )
73 Handlers_[p.fd].receiver(p.fd);
76 _DBG("end polling...");
87 void Waiter::RegisterFd(int fd, Receiver receiver)
89 // register fd should be caught in event loop
91 _DBG("Register fd %d", fd);
99 Fdlist_.push_back(info);
100 handler.info = &Fdlist_.back();
101 handler.receiver = receiver;
103 Handlers_[fd] = handler;
106 void Waiter::DeregisterFd(int fd)
108 // deregister fd should be caught in event loop
110 pollfd *info = Handlers_[fd].info;
111 Fdlist_.erase(Fdlist_.begin() - (info - &Fdlist_.front()));
115 int Waiter::WaitToLaunching(int argc, char *argv[])
118 auto on_create = [](bundle *extra, int type, void *user_data)
120 _DBG("on_create..."); // XXX
121 Waiter* waiter = static_cast<Waiter*>(user_data);
122 waiter->OnPrepared();
125 auto on_launch = [](int argc, char **argv, const char *app_path,
126 const char *appid, const char *pkgid,
127 const char *pkg_type, void *user_data) -> int
129 _DBG("on_launch..."); // XXX
130 Waiter* waiter = static_cast<Waiter*>(user_data);
132 _DBG ("app path : %s", app_path);
133 _DBG ("app id : %s", appid);
134 _DBG ("pkg id : %s", pkgid);
135 _DBG ("pkg type : %s", pkg_type);
144 waiter->OnRequested(info);
148 auto on_terminate = [](int argc, char **argv, void *user_data) -> int
150 _DBG("on_terminate..."); // XXX
152 string app_root(aul_get_app_root_path());
153 Waiter* waiter = static_cast<Waiter*>(user_data);
154 waiter->OnExecuted(argv[0], app_root.c_str(), argc, argv);
158 auto on_start_loop = [](void *user_data)
160 _DBG("on_start_loop..."); // XXX
161 Waiter* waiter = static_cast<Waiter*>(user_data);
165 auto on_quit_loop = [](void *user_data)
167 _DBG("on_quit_loop..."); // XXX
168 Waiter* waiter = static_cast<Waiter*>(user_data);
172 auto on_add_fd = [](void *user_data, int fd, loader_receiver_cb receiver)
174 _DBG("on_add_fd..."); // XXX
175 Waiter* waiter = static_cast<Waiter*>(user_data);
176 waiter->RegisterFd(fd, receiver);
179 auto on_remove_fd = [](void *user_data, int fd)
181 _DBG("on_remove_fd..."); // XXX
182 Waiter* waiter = static_cast<Waiter*>(user_data);
183 waiter->DeregisterFd(fd);
186 _DBG("launcher wait..."); // XXX
187 loader_lifecycle_callback_s callbacks = {
190 .terminate = on_terminate
193 loader_adapter_s adapter = {
194 .loop_begin = on_start_loop,
195 .loop_quit = on_quit_loop,
197 .remove_fd = on_remove_fd
200 return launchpad_loader_main(argc, argv, &callbacks, &adapter, this);
204 _DBG("not enough args : %d", argc);
207 _DBG("argv[1] = %s", argv[1]);
208 std::string app_path(argv[1]);
209 std::string app_root;
210 auto pos = app_path.find_last_of('/');
211 if (pos != std::string::npos)
212 app_root = app_path.substr(0, pos);
223 this->OnRequested(info);
224 this->OnExecuted(app_path.c_str(), app_root.c_str(), argc, argv);
228 void Waiter::SetContext(WaiterContext ctx)
233 WaiterContext::WaiterContext()
235 Step = Status::Started;
238 bool WaiterContext::Prepare()
240 if (Step == Status::Started && Prepared != nullptr && Prepared(Data) == 0)
242 Step = Status::Prepared;
248 bool WaiterContext::Request()
250 if (Step == Status::Prepared && Requested != nullptr && Requested(Data) == 0)
252 Step = Status::Requested;
258 bool WaiterContext::Execute(const char *path, const char *app_root, int argc, char *argv[])
260 if (Step == Status::Requested && Executed != nullptr &&
261 Executed(path, app_root, argc, argv, Data))
263 Step = Status::Executed;
269 } // namespace runtime
270 } // namespace dotnet
272 using dotnet::runtime::Waiter;
273 using dotnet::runtime::WaiterContext;
275 static Waiter waiter;
277 void register_launching_callback(prepared_callback prepared,
278 requested_callback requested, executed_callback executed, void *data)
280 WaiterContext context;
281 context.Prepared = prepared;
282 context.Requested = requested;
283 context.Executed = executed;
286 waiter.SetContext(context);
289 void wait_for_launching(int argc, char *argv[])
291 _DBG("wait_for_launching...");
293 waiter.WaitToLaunching(argc, argv);