⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.xs

📁 UNIX下perl实现代码
💻 XS
📖 第 1 页 / 共 2 页
字号:
static Signal_thandle_thread_signal(int sig){    dTHXo;    unsigned char c = (unsigned char) sig;    /*     * We're not really allowed to call fprintf in a signal handler     * so don't be surprised if this isn't robust while debugging     * with -DL.     */    DEBUG_S(PerlIO_printf(Perl_debug_log,	    "handle_thread_signal: got signal %d\n", sig););    write(sig_pipe[1], &c, 1);}MODULE = Thread		PACKAGE = ThreadPROTOTYPES: DISABLEvoidnew(classname, startsv, ...)	char *		classname	SV *		startsv	AV *		av = av_make(items - 2, &ST(2));    PPCODE:	XPUSHs(sv_2mortal(newthread(aTHX_ startsv, av, classname)));voidjoin(t)	Thread	t	AV *	av = NO_INIT	int	i = NO_INIT    PPCODE:#ifdef USE_THREADS	if (t == thr)	    croak("Attempt to join self");	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: joining %p (state %u)\n",			      thr, t, ThrSTATE(t)););    	MUTEX_LOCK(&t->mutex);	switch (ThrSTATE(t)) {	case THRf_R_JOINABLE:	case THRf_R_JOINED:	    ThrSETSTATE(t, THRf_R_JOINED);	    MUTEX_UNLOCK(&t->mutex);	    break;	case THRf_ZOMBIE:	    ThrSETSTATE(t, THRf_DEAD);	    MUTEX_UNLOCK(&t->mutex);	    remove_thread(aTHX_ t);	    break;	default:	    MUTEX_UNLOCK(&t->mutex);	    croak("can't join with thread");	    /* NOTREACHED */	}	JOIN(t, &av);	sv_2mortal((SV*)av);	if (SvTRUE(*av_fetch(av, 0, FALSE))) {	    /* Could easily speed up the following if necessary */	    for (i = 1; i <= AvFILL(av); i++)		XPUSHs(*av_fetch(av, i, FALSE));	}	else {	    STRLEN n_a;	    char *mess = SvPV(*av_fetch(av, 1, FALSE), n_a);	    DEBUG_S(PerlIO_printf(Perl_debug_log,				  "%p: join propagating die message: %s\n",				  thr, mess));	    croak(mess);	}#endifvoiddetach(t)	Thread	t    CODE:#ifdef USE_THREADS	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: detaching %p (state %u)\n",			      thr, t, ThrSTATE(t)););    	MUTEX_LOCK(&t->mutex);	switch (ThrSTATE(t)) {	case THRf_R_JOINABLE:	    ThrSETSTATE(t, THRf_R_DETACHED);	    /* fall through */	case THRf_R_DETACHED:	    DETACH(t);	    MUTEX_UNLOCK(&t->mutex);	    break;	case THRf_ZOMBIE:	    ThrSETSTATE(t, THRf_DEAD);	    DETACH(t);	    MUTEX_UNLOCK(&t->mutex);	    remove_thread(aTHX_ t);	    break;	default:	    MUTEX_UNLOCK(&t->mutex);	    croak("can't detach thread");	    /* NOTREACHED */	}#endifvoidequal(t1, t2)	Thread	t1	Thread	t2    PPCODE:	PUSHs((t1 == t2) ? &PL_sv_yes : &PL_sv_no);voidflags(t)	Thread	t    PPCODE:#ifdef USE_THREADS	PUSHs(sv_2mortal(newSViv(t->flags)));#endifvoidself(classname)	char *	classname    PREINIT:	SV *sv;    PPCODE:        #ifdef USE_THREADS	sv = newSViv(thr->tid);	sv_magic(sv, thr->oursv, '~', 0, 0);	SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;	PUSHs(sv_2mortal(sv_bless(newRV_noinc(sv),				  gv_stashpv(classname, TRUE))));#endifU32tid(t)	Thread	t    CODE:#ifdef USE_THREADS    	MUTEX_LOCK(&t->mutex);	RETVAL = t->tid;    	MUTEX_UNLOCK(&t->mutex);#else 	RETVAL = 0;#endif    OUTPUT:	RETVALvoidDESTROY(t)	SV *	t    PPCODE:	PUSHs(&PL_sv_yes);voidyield()    CODE:{#ifdef USE_THREADS	YIELD;#endif}voidcond_wait(sv)	SV *	sv	MAGIC *	mg = NO_INITCODE:                       #ifdef USE_THREADS	if (SvROK(sv))	    sv = SvRV(sv);	mg = condpair_magic(sv);	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: cond_wait %p\n", thr, sv));	MUTEX_LOCK(MgMUTEXP(mg));	if (MgOWNER(mg) != thr) {	    MUTEX_UNLOCK(MgMUTEXP(mg));	    croak("cond_wait for lock that we don't own\n");	}	MgOWNER(mg) = 0;	COND_SIGNAL(MgOWNERCONDP(mg));	COND_WAIT(MgCONDP(mg), MgMUTEXP(mg));	while (MgOWNER(mg))	    COND_WAIT(MgOWNERCONDP(mg), MgMUTEXP(mg));	MgOWNER(mg) = thr;	MUTEX_UNLOCK(MgMUTEXP(mg));#endifvoidcond_signal(sv)	SV *	sv	MAGIC *	mg = NO_INITCODE:#ifdef USE_THREADS	if (SvROK(sv))	    sv = SvRV(sv);	mg = condpair_magic(sv);	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: cond_signal %p\n",thr,sv));	MUTEX_LOCK(MgMUTEXP(mg));	if (MgOWNER(mg) != thr) {	    MUTEX_UNLOCK(MgMUTEXP(mg));	    croak("cond_signal for lock that we don't own\n");	}	COND_SIGNAL(MgCONDP(mg));	MUTEX_UNLOCK(MgMUTEXP(mg));#endifvoidcond_broadcast(sv)	SV *	sv	MAGIC *	mg = NO_INITCODE: #ifdef USE_THREADS	if (SvROK(sv))	    sv = SvRV(sv);	mg = condpair_magic(sv);	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: cond_broadcast %p\n",			      thr, sv));	MUTEX_LOCK(MgMUTEXP(mg));	if (MgOWNER(mg) != thr) {	    MUTEX_UNLOCK(MgMUTEXP(mg));	    croak("cond_broadcast for lock that we don't own\n");	}	COND_BROADCAST(MgCONDP(mg));	MUTEX_UNLOCK(MgMUTEXP(mg));#endifvoidlist(classname)	char *	classname    PREINIT:	Thread	t;	AV *	av;	SV **	svp;	int	n = 0;    PPCODE:#ifdef USE_THREADS	av = newAV();	/*	 * Iterate until we have enough dynamic storage for all threads.	 * We mustn't do any allocation while holding threads_mutex though.	 */	MUTEX_LOCK(&PL_threads_mutex);	do {	    n = PL_nthreads;	    MUTEX_UNLOCK(&PL_threads_mutex);	    if (AvFILL(av) < n - 1) {		int i = AvFILL(av);		for (i = AvFILL(av); i < n - 1; i++) {		    SV *sv = newSViv(0);	/* fill in tid later */		    sv_magic(sv, 0, '~', 0, 0);	/* fill in other magic later */		    av_push(av, sv_bless(newRV_noinc(sv),					 gv_stashpv(classname, TRUE)));			}	    }	    MUTEX_LOCK(&PL_threads_mutex);	} while (n < PL_nthreads);	n = PL_nthreads;	/* Get the final correct value */	/*	 * At this point, there's enough room to fill in av.	 * Note that we are holding threads_mutex so the list	 * won't change out from under us but all the remaining	 * processing is "fast" (no blocking, malloc etc.)	 */	t = thr;	svp = AvARRAY(av);	do {	    SV *sv = (SV*)SvRV(*svp);	    sv_setiv(sv, t->tid);	    SvMAGIC(sv)->mg_obj = SvREFCNT_inc(t->oursv);	    SvMAGIC(sv)->mg_flags |= MGf_REFCOUNTED;	    SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;	    t = t->next;	    svp++;	} while (t != thr);	/*  */	MUTEX_UNLOCK(&PL_threads_mutex);	/* Truncate any unneeded slots in av */	av_fill(av, n - 1);	/* Finally, push all the new objects onto the stack and drop av */	EXTEND(SP, n);	for (svp = AvARRAY(av); n > 0; n--, svp++)	    PUSHs(*svp);	(void)sv_2mortal((SV*)av);#endifMODULE = Thread		PACKAGE = Thread::Signalvoidkill_sighandler_thread()    PPCODE:	write(sig_pipe[1], "\0", 1);	PUSHs(&PL_sv_yes);voidinit_thread_signals()    PPCODE:	PL_sighandlerp = handle_thread_signal;	if (pipe(sig_pipe) == -1)	    XSRETURN_UNDEF;	PUSHs(&PL_sv_yes);voidawait_signal()    PREINIT:	unsigned char c;	SSize_t ret;    CODE:	do {	    ret = read(sig_pipe[0], &c, 1);	} while (ret == -1 && errno == EINTR);	if (ret == -1)	    croak("panic: await_signal");	ST(0) = sv_newmortal();	if (ret)	    sv_setsv(ST(0), c ? PL_psig_ptr[c] : &PL_sv_no);	DEBUG_S(PerlIO_printf(Perl_debug_log,			      "await_signal returning %s\n", SvPEEK(ST(0))););MODULE = Thread		PACKAGE = Thread::Specificvoiddata(classname = "Thread::Specific")	char *	classname    PPCODE:#ifdef USE_THREADS	if (AvFILL(thr->specific) == -1) {	    GV *gv = gv_fetchpv("Thread::Specific::FIELDS", TRUE, SVt_PVHV);	    av_store(thr->specific, 0, newRV((SV*)GvHV(gv)));	}	XPUSHs(sv_bless(newRV((SV*)thr->specific),gv_stashpv(classname,TRUE)));#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -