0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 18:18:56 +02:00

ircd::js: Task identification (PID) and reference counted management.

This commit is contained in:
Jason Volk 2016-10-31 12:12:43 -07:00
parent cca79d87fc
commit d2b3bedca6
3 changed files with 48 additions and 11 deletions

View file

@ -75,6 +75,8 @@ struct context
void handle_timeout() noexcept; // Called by timer after requested time
struct timer timer;
std::map<uint64_t, struct task *> tasks; // Active processes
// JSContext
operator JSContext *() const { return get(); }
operator JSContext &() const { return custom_ptr<JSContext>::operator*(); }

View file

@ -26,28 +26,26 @@ namespace ircd {
namespace js {
struct task
:std::enable_shared_from_this<task>
{
uint64_t pid;
struct global global; // global / this / root scope object
heap_function main; // main generator wrapper function
struct generator generator; // generator state
// Invokes next() on the generator
template<class... args> value operator()(args&&...);
private:
static uint64_t tasks_next_pid();
uint64_t tasks_insert();
bool tasks_remove();
public:
task(const std::string &source);
task() = default;
~task() noexcept;
static task &get(const object &global);
static task &get();
};
template<class... args>
value
task::operator()(args&&... a)
{
return generator.next(std::forward<args>(a)...);
}
inline task &
task::get()
{

View file

@ -143,7 +143,12 @@ js::ReportOutOfMemory(ExclusiveContext *const c)
//
ircd::js::task::task(const std::string &source)
:global{[this]
try
:pid
{
tasks_insert()
}
,global{[this]
{
// Global object is constructed using the root trap (JSClass) at *tree;
// This is a thread_local registered by the kernel.so module.
@ -190,6 +195,38 @@ ircd::js::task::task(const std::string &source)
}()}
{
}
catch(const std::exception &e)
{
tasks_remove();
}
ircd::js::task::~task()
noexcept
{
tasks_remove();
}
bool
ircd::js::task::tasks_remove()
{
return cx->tasks.erase(pid);
}
uint64_t
ircd::js::task::tasks_insert()
{
const uint64_t pid(tasks_next_pid());
const auto iit(cx->tasks.emplace(pid, this));
assert(iit.second);
return pid;
}
uint64_t
ircd::js::task::tasks_next_pid()
{
auto &tasks(cx->tasks);
return tasks.empty()? 0 : std::prev(std::end(tasks))->first + 1;
}
///////////////////////////////////////////////////////////////////////////////
//