EV-Loop-Async

 view release on metacpan or  search on metacpan

Async.xs  view on Meta::CPAN

      X_COND_WAIT (u->invoke_cv, u->lock);
    }
}

static void
loop_set_cb (EV_P)
{
  ev_set_invoke_pending_cb (EV_A, l_invoke);
  ev_set_loop_release_cb (EV_A, l_release, l_acquire);
}

X_THREAD_PROC(l_run)
{
  struct ev_loop *loop = (struct ev_loop *)thr_arg;
#if defined(_WIN32) && defined(USE_ITHREADS)
  udat *u = ev_userdata (EV_A);

  /* just setting the same context pointer as the other thread is */
  /* probably fatal, yet, I have no clue what makes libev crash (malloc?) */
  /* as visual c also crashes when it tries to debug the crash */
  /* the loser platform is indeed a crashy OS */
  PERL_SET_CONTEXT (u->thx);
#endif

  l_acquire (EV_A);

  /* yeah */
  pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);

  ev_ref (EV_A);
  ev_run (EV_A, 0);
  ev_unref (EV_A);

  l_release (EV_A);

  return 0;
}

static void
scope_lock_cb (pTHX_ void *loop_)
{
  struct ev_loop *loop = (struct ev_loop *)SvIVX ((SV *)loop_);
  udat *u = ev_userdata (EV_A);

  X_UNLOCK (u->lock);
  SvREFCNT_dec ((SV *)loop_);
}

MODULE = EV::Loop::Async                PACKAGE = EV::Loop::Async

PROTOTYPES: ENABLE

BOOT:
{
	I_EV_API ("EV::Loop::Async");
        CvNODEBUG_on (get_cv ("EV::Loop::Async::scope_lock", 0)); /* otherwise calling scope can be the debugger */
}

void
_c_func (SV *loop)
	PPCODE:
        EXTEND (SP, 2);
        PUSHs (sv_2mortal (newSViv (PTR2IV (c_func))));
        PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop)))));

void
_attach (SV *loop_, SV *interrupt, IV sig_func, void *sig_arg)
        PROTOTYPE: @
	CODE:
{
  	pthread_mutexattr_t ma;
	struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_));
  	udat *u;

        Newz (0, u, 1, udat);
        u->interrupt   = newSVsv (interrupt);
        u->signal_func = (void (*)(void *, int))sig_func;
        u->signal_arg  = sig_arg;
#if defined(_WIN32) && defined(USE_ITHREADS)
        u->thx         = PERL_GET_CONTEXT;
#endif

        ev_async_init (&u->async_w, async_cb);
        ev_async_start (EV_A, &u->async_w);

        pthread_mutexattr_init (&ma);
#ifdef PTHREAD_MUTEX_RECURSIVE
        pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE);
#else
        pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE_NP);
#endif
        pthread_mutex_init (&u->lock, &ma);
        pthread_mutexattr_destroy (&ma);

        pthread_cond_init (&u->invoke_cv, 0);

        ev_set_userdata (EV_A, u);
        loop_set_cb (EV_A);

        thread_create (&u->tid, l_run, loop);
}

SV *
interrupt (SV *loop_)
	CODE:
{
	struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_));
  	udat *u = ev_userdata (EV_A);

        RETVAL = newSVsv (u->interrupt);
}
	OUTPUT:
        RETVAL

void
set_max_foreground_loops (SV *loop_, UV max_loops)
	CODE:
{
	struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_));
  	udat *u = ev_userdata (EV_A);



( run in 0.813 second using v1.01-cache-2.11-cpan-5511b514fd6 )