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

📄 shared.xs

📁 source of perl for linux application,
💻 XS
📖 第 1 页 / 共 3 页
字号:
        dTHXc;        SHARED_CONTEXT;        SvREFCNT_dec(ssv);        CALLER_CONTEXT;    }    LEAVE_LOCK;}/* Implements Perl-level share() and :shared */voidPerl_sharedsv_share(pTHX_ SV *sv){    switch(SvTYPE(sv)) {    case SVt_PVGV:        Perl_croak(aTHX_ "Cannot share globs yet");        break;    case SVt_PVCV:        Perl_croak(aTHX_ "Cannot share subs yet");        break;    default:        ENTER_LOCK;        (void) S_sharedsv_new_shared(aTHX_ sv);        LEAVE_LOCK;        SvSETMAGIC(sv);        break;    }}#ifdef WIN32/* Number of milliseconds from 1/1/1601 to 1/1/1970 */#define EPOCH_BIAS      11644473600000./* Returns relative time in milliseconds.  (Adapted from Time::HiRes.) */STATIC DWORDS_abs_2_rel_milli(double abs){    double rel;    /* Get current time (in units of 100 nanoseconds since 1/1/1601) */    union {        FILETIME ft;        __int64  i64;   /* 'signed' to keep compilers happy */    } now;    GetSystemTimeAsFileTime(&now.ft);    /* Relative time in milliseconds */    rel = (abs * 1000.) - (((double)now.i64 / 10000.) - EPOCH_BIAS);    if (rel <= 0.0) {        return (0);    }    return (DWORD)rel;}#else# if defined(OS2)#  define ABS2RELMILLI(abs)             \    do {                                \        abs -= (double)time(NULL);      \        if (abs > 0) { abs *= 1000; }   \        else         { abs  = 0;    }   \    } while (0)# endif /* OS2 */#endif /* WIN32 *//* Do OS-specific condition timed wait */boolPerl_sharedsv_cond_timedwait(perl_cond *cond, perl_mutex *mut, double abs){#if defined(NETWARE) || defined(FAKE_THREADS) || defined(I_MACH_CTHREADS)    Perl_croak_nocontext("cond_timedwait not supported on this platform");#else#  ifdef WIN32    int got_it = 0;    cond->waiters++;    MUTEX_UNLOCK(mut);    /* See comments in win32/win32thread.h COND_WAIT vis-a-vis race */    switch (WaitForSingleObject(cond->sem, S_abs_2_rel_milli(abs))) {        case WAIT_OBJECT_0:   got_it = 1; break;        case WAIT_TIMEOUT:                break;        default:            /* WAIT_FAILED? WAIT_ABANDONED? others? */            Perl_croak_nocontext("panic: cond_timedwait (%ld)",GetLastError());            break;    }    MUTEX_LOCK(mut);    cond->waiters--;    return (got_it);#  else#    ifdef OS2    int rc, got_it = 0;    STRLEN n_a;    ABS2RELMILLI(abs);    if ((rc = DosResetEventSem(*cond,&n_a)) && (rc != ERROR_ALREADY_RESET))        Perl_rc = rc, croak_with_os2error("panic: cond_timedwait-reset");    MUTEX_UNLOCK(mut);    if (CheckOSError(DosWaitEventSem(*cond,abs))        && (rc != ERROR_INTERRUPT))        croak_with_os2error("panic: cond_timedwait");    if (rc == ERROR_INTERRUPT) errno = EINTR;    MUTEX_LOCK(mut);    return (got_it);#    else         /* Hope you're I_PTHREAD! */    struct timespec ts;    int got_it = 0;    ts.tv_sec = (long)abs;    abs -= (NV)ts.tv_sec;    ts.tv_nsec = (long)(abs * 1000000000.0);    switch (pthread_cond_timedwait(cond, mut, &ts)) {        case 0:         got_it = 1; break;        case ETIMEDOUT:             break;#ifdef OEMVS        case -1:            if (errno == ETIMEDOUT || errno == EAGAIN)                break;#endif        default:            Perl_croak_nocontext("panic: cond_timedwait");            break;    }    return (got_it);#    endif /* OS2 */#  endif /* WIN32 */#endif /* NETWARE || FAKE_THREADS || I_MACH_CTHREADS */}/* Given a shared RV, copy it's value to a private RV, also copying the * object status of the referent. * If the private side is already an appropriate RV->SV combination, keep * it if possible. */STATIC voidS_get_RV(pTHX_ SV *sv, SV *ssv) {    SV *sobj = SvRV(ssv);    SV *obj;    if (! (SvROK(sv) &&           ((obj = SvRV(sv))) &&           (Perl_sharedsv_find(aTHX_ obj) == sobj) &&           (SvTYPE(obj) == SvTYPE(sobj))))    {        /* Can't reuse obj */        if (SvROK(sv)) {            SvREFCNT_dec(SvRV(sv));        } else {            assert(SvTYPE(sv) >= SVt_RV);            sv_setsv_nomg(sv, &PL_sv_undef);            SvROK_on(sv);        }        obj = S_sharedsv_new_private(aTHX_ SvRV(ssv));        SvRV_set(sv, obj);    }    if (SvOBJECT(obj)) {        /* Remove any old blessing */        SvREFCNT_dec(SvSTASH(obj));        SvOBJECT_off(obj);    }    if (SvOBJECT(sobj)) {        /* Add any new old blessing */        STRLEN len;        char* stash_ptr = SvPV((SV*) SvSTASH(sobj), len);        HV* stash = gv_stashpvn(stash_ptr, len, TRUE);        SvOBJECT_on(obj);        SvSTASH_set(obj, (HV*)SvREFCNT_inc(stash));    }}/* ------------ PERL_MAGIC_shared_scalar(n) functions -------------- *//* Get magic for PERL_MAGIC_shared_scalar(n) */intsharedsv_scalar_mg_get(pTHX_ SV *sv, MAGIC *mg){    SV *ssv = (SV *) mg->mg_ptr;    assert(ssv);    ENTER_LOCK;    if (SvROK(ssv)) {        S_get_RV(aTHX_ sv, ssv);    } else {        sv_setsv_nomg(sv, ssv);    }    LEAVE_LOCK;    return (0);}/* Copy the contents of a private SV to a shared SV. * Used by various mg_set()-type functions. * Assumes lock is held. */voidsharedsv_scalar_store(pTHX_ SV *sv, SV *ssv){    dTHXc;    bool allowed = TRUE;    assert(PL_sharedsv_lock.owner == aTHX);    if (SvROK(sv)) {        SV *obj = SvRV(sv);        SV *sobj = Perl_sharedsv_find(aTHX_ obj);        if (sobj) {            SHARED_CONTEXT;            (void)SvUPGRADE(ssv, SVt_RV);            sv_setsv_nomg(ssv, &PL_sv_undef);            SvRV_set(ssv, SvREFCNT_inc(sobj));            SvROK_on(ssv);            if (SvOBJECT(sobj)) {                /* Remove any old blessing */                SvREFCNT_dec(SvSTASH(sobj));                SvOBJECT_off(sobj);            }            if (SvOBJECT(obj)) {              SV* fake_stash = newSVpv(HvNAME_get(SvSTASH(obj)),0);              SvOBJECT_on(sobj);              SvSTASH_set(sobj, (HV*)fake_stash);            }            CALLER_CONTEXT;        } else {            allowed = FALSE;        }    } else {        SvTEMP_off(sv);        SHARED_CONTEXT;        sv_setsv_nomg(ssv, sv);        if (SvOBJECT(ssv)) {            /* Remove any old blessing */            SvREFCNT_dec(SvSTASH(ssv));            SvOBJECT_off(ssv);        }        if (SvOBJECT(sv)) {          SV* fake_stash = newSVpv(HvNAME_get(SvSTASH(sv)),0);          SvOBJECT_on(ssv);          SvSTASH_set(ssv, (HV*)fake_stash);        }        CALLER_CONTEXT;    }    if (!allowed) {        Perl_croak(aTHX_ "Invalid value for shared scalar");    }}/* Set magic for PERL_MAGIC_shared_scalar(n) */intsharedsv_scalar_mg_set(pTHX_ SV *sv, MAGIC *mg){    SV *ssv = (SV*)(mg->mg_ptr);    assert(ssv);    ENTER_LOCK;    if (SvTYPE(ssv) < SvTYPE(sv)) {        dTHXc;        SHARED_CONTEXT;        sv_upgrade(ssv, SvTYPE(sv));        CALLER_CONTEXT;    }    sharedsv_scalar_store(aTHX_ sv, ssv);    LEAVE_LOCK;    return (0);}/* Free magic for PERL_MAGIC_shared_scalar(n) */intsharedsv_scalar_mg_free(pTHX_ SV *sv, MAGIC *mg){    S_sharedsv_dec(aTHX_ (SV*)mg->mg_ptr);    return (0);}/* * Called during cloning of PERL_MAGIC_shared_scalar(n) magic in new thread */intsharedsv_scalar_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param){    SvREFCNT_inc_void(mg->mg_ptr);    return (0);}#ifdef MGf_LOCAL/* * Called during local $shared */intsharedsv_scalar_mg_local(pTHX_ SV* nsv, MAGIC *mg){    MAGIC *nmg;    SV *ssv = (SV *) mg->mg_ptr;    if (ssv) {        ENTER_LOCK;        SvREFCNT_inc_void(ssv);        LEAVE_LOCK;    }    nmg = sv_magicext(nsv, mg->mg_obj, mg->mg_type, mg->mg_virtual,                           mg->mg_ptr, mg->mg_len);    nmg->mg_flags   = mg->mg_flags;    nmg->mg_private = mg->mg_private;    return (0);}#endifMGVTBL sharedsv_scalar_vtbl = {    sharedsv_scalar_mg_get,     /* get */    sharedsv_scalar_mg_set,     /* set */    0,                          /* len */    0,                          /* clear */    sharedsv_scalar_mg_free,    /* free */    0,                          /* copy */    sharedsv_scalar_mg_dup,     /* dup */#ifdef MGf_LOCAL    sharedsv_scalar_mg_local,   /* local */#endif};/* ------------ PERL_MAGIC_tiedelem(p) functions -------------- *//* Get magic for PERL_MAGIC_tiedelem(p) */intsharedsv_elem_mg_FETCH(pTHX_ SV *sv, MAGIC *mg){    dTHXc;    SV *saggregate = S_sharedsv_from_obj(aTHX_ mg->mg_obj);    SV** svp;    ENTER_LOCK;    if (SvTYPE(saggregate) == SVt_PVAV) {        assert ( mg->mg_ptr == 0 );        SHARED_CONTEXT;        svp = av_fetch((AV*) saggregate, mg->mg_len, 0);    } else {        char *key = mg->mg_ptr;        STRLEN len = mg->mg_len;        assert ( mg->mg_ptr != 0 );        if (mg->mg_len == HEf_SVKEY) {           key = SvPV((SV *) mg->mg_ptr, len);        }        SHARED_CONTEXT;        svp = hv_fetch((HV*) saggregate, key, len, 0);    }    CALLER_CONTEXT;    if (svp) {        /* Exists in the array */        if (SvROK(*svp)) {            S_get_RV(aTHX_ sv, *svp);        } else {            /* XXX Can this branch ever happen? DAPM */            /* XXX assert("no such branch"); */            Perl_sharedsv_associate(aTHX_ sv, *svp);            sv_setsv(sv, *svp);        }    } else {        /* Not in the array */        sv_setsv(sv, &PL_sv_undef);    }    LEAVE_LOCK;    return (0);}/* Set magic for PERL_MAGIC_tiedelem(p) */intsharedsv_elem_mg_STORE(pTHX_ SV *sv, MAGIC *mg){    dTHXc;    SV *saggregate = S_sharedsv_from_obj(aTHX_ mg->mg_obj);    SV **svp;    /* Theory - SV itself is magically shared - and we have ordered the       magic such that by the time we get here it has been stored       to its shared counterpart     */    ENTER_LOCK;    assert(saggregate);    if (SvTYPE(saggregate) == SVt_PVAV) {        assert ( mg->mg_ptr == 0 );        SHARED_CONTEXT;        svp = av_fetch((AV*) saggregate, mg->mg_len, 1);    } else {        char *key = mg->mg_ptr;        STRLEN len = mg->mg_len;        assert ( mg->mg_ptr != 0 );        if (mg->mg_len == HEf_SVKEY)           key = SvPV((SV *) mg->mg_ptr, len);        SHARED_CONTEXT;        svp = hv_fetch((HV*) saggregate, key, len, 1);    }    CALLER_CONTEXT;    Perl_sharedsv_associate(aTHX_ sv, *svp);    sharedsv_scalar_store(aTHX_ sv, *svp);    LEAVE_LOCK;    return (0);}/* Clear magic for PERL_MAGIC_tiedelem(p) */intsharedsv_elem_mg_DELETE(pTHX_ SV *sv, MAGIC *mg){    dTHXc;    MAGIC *shmg;    SV *saggregate = S_sharedsv_from_obj(aTHX_ mg->mg_obj);    ENTER_LOCK;    sharedsv_elem_mg_FETCH(aTHX_ sv, mg);    if ((shmg = mg_find(sv, PERL_MAGIC_shared_scalar)))        sharedsv_scalar_mg_get(aTHX_ sv, shmg);    if (SvTYPE(saggregate) == SVt_PVAV) {        SHARED_CONTEXT;        av_delete((AV*) saggregate, mg->mg_len, G_DISCARD);    } else {        char *key = mg->mg_ptr;        STRLEN len = mg->mg_len;        assert ( mg->mg_ptr != 0 );        if (mg->mg_len == HEf_SVKEY)           key = SvPV((SV *) mg->mg_ptr, len);        SHARED_CONTEXT;        hv_delete((HV*) saggregate, key, len, G_DISCARD);    }    CALLER_CONTEXT;    LEAVE_LOCK;    return (0);}/* Called during cloning of PERL_MAGIC_tiedelem(p) magic in new * thread */intsharedsv_elem_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param){    SvREFCNT_inc_void(S_sharedsv_from_obj(aTHX_ mg->mg_obj));    assert(mg->mg_flags & MGf_DUP);    return (0);}MGVTBL sharedsv_elem_vtbl = {    sharedsv_elem_mg_FETCH,     /* get */    sharedsv_elem_mg_STORE,     /* set */    0,                          /* len */    sharedsv_elem_mg_DELETE,    /* clear */    0,                          /* free */    0,                          /* copy */    sharedsv_elem_mg_dup,       /* dup */#ifdef MGf_LOCAL    0,                          /* local */#endif};/* ------------ PERL_MAGIC_tied(P) functions -------------- *//* Len magic for PERL_MAGIC_tied(P) */U32sharedsv_array_mg_FETCHSIZE(pTHX_ SV *sv, MAGIC *mg){    dTHXc;    SV *ssv = (SV *) mg->mg_ptr;    U32 val;    SHARED_EDIT;    if (SvTYPE(ssv) == SVt_PVAV) {        val = av_len((AV*) ssv);    } else {        /* Not actually defined by tie API but ... */        val = HvKEYS((HV*) ssv);    }    SHARED_RELEASE;    return (val);}/* Clear magic for PERL_MAGIC_tied(P) */intsharedsv_array_mg_CLEAR(pTHX_ SV *sv, MAGIC *mg){    dTHXc;    SV *ssv = (SV *) mg->mg_ptr;    SHARED_EDIT;    if (SvTYPE(ssv) == SVt_PVAV) {        av_clear((AV*) ssv);    } else {        hv_clear((HV*) ssv);    }    SHARED_RELEASE;    return (0);}/* Free magic for PERL_MAGIC_tied(P) */intsharedsv_array_mg_free(pTHX_ SV *sv, MAGIC *mg){    S_sharedsv_dec(aTHX_ (SV*)mg->mg_ptr);    return (0);}/* * Copy magic for PERL_MAGIC_tied(P) * This is called when perl is about to access an element of * the array - */intsharedsv_array_mg_copy(pTHX_ SV *sv, MAGIC* mg,                       SV *nsv, const char *name, int namlen){    MAGIC *nmg = sv_magicext(nsv,mg->mg_obj,                            toLOWER(mg->mg_type),&sharedsv_elem_vtbl,                            name, namlen);

⌨️ 快捷键说明

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