Permalink
Browse files

process, feat: use ev to wait child process in real async mode.

  • Loading branch information...
xicilion committed Nov 10, 2017
1 parent a465964 commit 2dbe78cd29563660441f066a1f490c1d8e53d1e4
Showing with 83 additions and 12 deletions.
  1. +2 −0 fibjs/include/AsyncIO.h
  2. +41 −0 fibjs/src/io/AsyncIO_ev.cpp
  3. +39 −11 fibjs/src/process/SubProcess_posix.cpp
  4. +1 −1 vender
View
@@ -69,6 +69,8 @@ class AsyncIO {
}
#endif
static result_t waitpid(intptr_t pid, int32_t& retVal, AsyncEvent* ac);
public:
intptr_t m_fd;
int32_t m_family;
@@ -653,6 +653,47 @@ result_t AsyncIO::recvfrom(int32_t bytes, obj_ptr<NObject>& retVal,
return (new asyncRecvFrom(m_fd, bytes, retVal, ac, m_lockRecv, m_RecvOpt))->call();
}
result_t AsyncIO::waitpid(intptr_t pid, int32_t& retVal, AsyncEvent* ac)
{
class asyncWaitPid : public asyncEv {
public:
asyncWaitPid(intptr_t pid, int32_t& retVal, AsyncEvent* ac)
: m_ac(ac)
, m_pid(pid)
, m_retVal(retVal)
{
}
virtual void start()
{
ev_child_init(&cw, child_cb, m_pid, 0);
ev_child_start(s_loop, &cw);
}
private:
static void child_cb(struct ev_loop* loop, struct ev_child* w, int revents)
{
asyncWaitPid* pThis = NULL;
pThis = (asyncWaitPid*)((intptr_t)w - (intptr_t)&pThis->cw);
pThis->m_retVal = w->rstatus;
ev_child_stop(loop, w);
pThis->m_ac->apost(0);
delete pThis;
}
public:
AsyncEvent* m_ac;
intptr_t m_pid;
int32_t& m_retVal;
ev_child cw;
};
(new asyncWaitPid(pid, retVal, ac))->post();
return CALL_E_PENDDING;
}
}
#endif
@@ -206,21 +206,49 @@ result_t SubProcess::kill(int32_t signal)
result_t SubProcess::wait(int32_t& retVal, AsyncEvent* ac)
{
if (ac->isSync())
return CHECK_ERROR(CALL_E_LONGSYNC);
class asyncWaitPid : public AsyncState {
public:
asyncWaitPid(intptr_t pid, Timer* timer, int32_t& retVal, AsyncEvent* ac)
: AsyncState(ac)
, m_pid(pid)
, m_timer(timer)
, m_retVal(retVal)
{
set(wait);
}
int32_t status;
waitpid(m_pid, &status, 0);
public:
static int32_t wait(AsyncState* pState, int32_t n)
{
asyncWaitPid* pThis = (asyncWaitPid*)pState;
if (!WIFEXITED(status))
retVal = status;
else
retVal = WEXITSTATUS(status);
pThis->set(result);
return AsyncIO::waitpid(pThis->m_pid, pThis->m_retVal, pThis);
}
if (m_timer)
m_timer->clear();
static int32_t result(AsyncState* pState, int32_t n)
{
asyncWaitPid* pThis = (asyncWaitPid*)pState;
return 0;
if (WIFEXITED(pThis->m_retVal))
pThis->m_retVal = WEXITSTATUS(pThis->m_retVal);
if (pThis->m_timer)
pThis->m_timer->clear();
return pThis->done();
}
private:
intptr_t m_pid;
obj_ptr<Timer> m_timer;
int32_t& m_retVal;
};
if (ac->isSync())
return CHECK_ERROR(CALL_E_NOSYNC);
return (new asyncWaitPid(m_pid, m_timer, retVal, ac))->post(0);
}
result_t SubProcess::findWindow(exlib::string name, v8::Local<v8::Value>& retVal)
2 vender
Submodule vender updated 1 files
+1 −1 ev/ev.h

0 comments on commit 2dbe78c

Please sign in to comment.