/*
 * This file was generated automatically by ExtUtils::ParseXS version 2.2203 from the
 * contents of StaticVariable.xs. Do not edit this file, edit StaticVariable.xs instead.
 *
 *	ANY CHANGES MADE HERE WILL BE LOST! 
 *
 */

#line 1 "lib/Global/IPC/StaticVariable.xs"
#ifdef __cplusplus
extern "C" {
#endif

#define PERL_NO_GET_CONTEXT /* we want efficiency */
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include <sys/shm.h>
#include <string.h>
#include <pthread.h>

#define MAX_VARSIZE 536870912 // 512MB

typedef struct {
    pthread_mutex_t m;
    char str[MAX_VARSIZE];
    int len;
} SharedObject;

void clear_sharedobject(SharedObject *o) {
    memset(o->str, '\0', MAX_VARSIZE);
    o->len = 0;
}

void init_sharedobject(SharedObject *o) {
    pthread_mutexattr_t mat;
    pthread_mutexattr_init(&mat);
    pthread_mutexattr_setpshared(&mat, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&(o->m), &mat);
    clear_sharedobject(o);
}

#ifdef __cplusplus
} /* extern "C" */
#endif

#include "ppport.h"

#line 50 "temp/StaticVariable.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
            Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params);
        else
            Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
        Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#ifdef PERL_IMPLICIT_CONTEXT
#define croak_xs_usage(a,b)	S_croak_xs_usage(aTHX_ a,b)
#else
#define croak_xs_usage		S_croak_xs_usage
#endif

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#line 102 "temp/StaticVariable.c"

XS(XS_Global__IPC__StaticVariable_var_create); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_create)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
#line 48 "lib/Global/IPC/StaticVariable.xs"
    SharedObject *o;
    int shmid = -1;
#line 118 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 51 "lib/Global/IPC/StaticVariable.xs"
    if ((shmid = shmget(IPC_PRIVATE, sizeof(SharedObject), 0666))!=-1) {
        o = (SharedObject*)shmat(shmid, NULL, 0);
        init_sharedobject(o);
        RETVAL = newSViv(shmid);
    } else {
        RETVAL = &PL_sv_undef;
    }
#line 128 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS(XS_Global__IPC__StaticVariable_var_destory); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_destory)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 1)
       croak_xs_usage(cv,  "sv_shmid");
    {
	SV*	sv_shmid = ST(0);
#line 65 "lib/Global/IPC/StaticVariable.xs"
    int shmid = -1;
#line 150 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 67 "lib/Global/IPC/StaticVariable.xs"
    if (SvOK(sv_shmid)) {
        shmid = SvIV(sv_shmid);
    }
    if (shmid == -1 || shmctl(shmid, IPC_RMID, NULL) != 0) {
        RETVAL = &PL_sv_undef;
    } else {
        RETVAL = newSViv(1);
    }
#line 161 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS(XS_Global__IPC__StaticVariable_var_update); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_update)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 2)
       croak_xs_usage(cv,  "sv_shmid, sv_str");
    {
	SV*	sv_shmid = ST(0);
	SV*	sv_str = ST(1);
#line 83 "lib/Global/IPC/StaticVariable.xs"
    SharedObject *o = NULL;
    int shmid = -1;
    STRLEN sv_str_len = 0;
    char *ptr_sv_str = NULL;
#line 187 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 88 "lib/Global/IPC/StaticVariable.xs"
    if (SvOK(sv_shmid)) {
        shmid = SvIV(sv_shmid);
        if (shmid != -1) o = (SharedObject*)shmat(shmid, NULL, 0);
    }
    if (o != NULL && (long)o != -1) {
        if (SvOK(sv_str)) ptr_sv_str = SvPV(sv_str, sv_str_len);
        pthread_mutex_lock(&(o->m));
        if (sv_str_len == 0) {
            clear_sharedobject(o);
        } else {
            if (o->len) memset(o->str, '\0', o->len);
            strncpy(o->str, ptr_sv_str, sv_str_len);
            o->len = sv_str_len;
        }
        pthread_mutex_unlock(&(o->m));
        RETVAL = newSViv(1);
    } else {
        RETVAL = &PL_sv_undef;
    }
#line 209 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS(XS_Global__IPC__StaticVariable_var_read); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_read)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 1)
       croak_xs_usage(cv,  "sv_shmid");
    {
	SV*	sv_shmid = ST(0);
#line 114 "lib/Global/IPC/StaticVariable.xs"
    SharedObject *o = NULL;
    int shmid = -1;
#line 232 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 117 "lib/Global/IPC/StaticVariable.xs"
    if (SvOK(sv_shmid)) {
        shmid = SvIV(sv_shmid);
        if (shmid != -1) o = (SharedObject*)shmat(shmid, NULL, 0);
    }
    if (o != NULL && (long)o != -1) {
        RETVAL = newSVpvn(o->str, o->len);
    } else {
        RETVAL = &PL_sv_undef;
    }
#line 244 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS(XS_Global__IPC__StaticVariable_var_append); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_append)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 2)
       croak_xs_usage(cv,  "sv_shmid, sv_str");
    {
	SV*	sv_shmid = ST(0);
	SV*	sv_str = ST(1);
#line 134 "lib/Global/IPC/StaticVariable.xs"
    SharedObject *o = NULL;
    int shmid = -1;
    STRLEN sv_str_len = 0;
    char *ptr_sv_str = NULL, *tmp_ptr = NULL;
#line 270 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 139 "lib/Global/IPC/StaticVariable.xs"
    if (SvOK(sv_shmid) && SvOK(sv_str)) {
        ptr_sv_str = SvPV(sv_str, sv_str_len);
        if (ptr_sv_str && sv_str_len > 0) {
            shmid = SvIV(sv_shmid);
            if (shmid != -1) o = (SharedObject*)shmat(shmid, NULL, 0);
            if (o != NULL && (long)o != -1) {
                pthread_mutex_lock(&(o->m));
                tmp_ptr = o->str + o->len;
                strncpy(tmp_ptr, ptr_sv_str, sv_str_len);
                o->len += sv_str_len;
                pthread_mutex_unlock(&(o->m));
                RETVAL = newSViv(1);
            } else {
                RETVAL = &PL_sv_undef;
            }
        } else {
            RETVAL = &PL_sv_undef;
        }
    } else {
        RETVAL = &PL_sv_undef;
    }
#line 294 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS(XS_Global__IPC__StaticVariable_var_getreset); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_getreset)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 1)
       croak_xs_usage(cv,  "sv_shmid");
    {
	SV*	sv_shmid = ST(0);
#line 167 "lib/Global/IPC/StaticVariable.xs"
    SharedObject *o = NULL;
    int shmid = -1;
#line 317 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 170 "lib/Global/IPC/StaticVariable.xs"
    if (SvOK(sv_shmid)) {
        shmid = SvIV(sv_shmid);
        if (shmid != -1) o = (SharedObject*)shmat(shmid, NULL, 0);
    }
    if (o != NULL && (long)o != -1) {
        pthread_mutex_lock(&(o->m));
        RETVAL = newSVpvn(o->str, o->len);
        clear_sharedobject(o);
        pthread_mutex_unlock(&(o->m));
    } else {
        RETVAL = &PL_sv_undef;
    }
#line 332 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS(XS_Global__IPC__StaticVariable_var_length); /* prototype to pass -Wmissing-prototypes */
XS(XS_Global__IPC__StaticVariable_var_length)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
    if (items != 1)
       croak_xs_usage(cv,  "sv_shmid");
    {
	SV*	sv_shmid = ST(0);
#line 189 "lib/Global/IPC/StaticVariable.xs"
    SharedObject *o = NULL;
    int shmid = -1;
#line 355 "temp/StaticVariable.c"
	SV *	RETVAL;
#line 192 "lib/Global/IPC/StaticVariable.xs"
    if (SvOK(sv_shmid)) {
        shmid = SvIV(sv_shmid);
        if (shmid != -1) o = (SharedObject*)shmat(shmid, NULL, 0);
    }
    if (o != NULL && (long)o != -1) {
        RETVAL = newSViv(o->len);
    } else {
        RETVAL = &PL_sv_undef;
    }
#line 367 "temp/StaticVariable.c"
	ST(0) = RETVAL;
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}

#ifdef __cplusplus
extern "C"
#endif
XS(boot_Global__IPC__StaticVariable); /* prototype to pass -Wmissing-prototypes */
XS(boot_Global__IPC__StaticVariable)
{
#ifdef dVAR
    dVAR; dXSARGS;
#else
    dXSARGS;
#endif
#if (PERL_REVISION == 5 && PERL_VERSION < 9)
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    XS_VERSION_BOOTCHECK ;

        newXS("Global::IPC::StaticVariable::var_create", XS_Global__IPC__StaticVariable_var_create, file);
        newXS("Global::IPC::StaticVariable::var_destory", XS_Global__IPC__StaticVariable_var_destory, file);
        newXS("Global::IPC::StaticVariable::var_update", XS_Global__IPC__StaticVariable_var_update, file);
        newXS("Global::IPC::StaticVariable::var_read", XS_Global__IPC__StaticVariable_var_read, file);
        newXS("Global::IPC::StaticVariable::var_append", XS_Global__IPC__StaticVariable_var_append, file);
        newXS("Global::IPC::StaticVariable::var_getreset", XS_Global__IPC__StaticVariable_var_getreset, file);
        newXS("Global::IPC::StaticVariable::var_length", XS_Global__IPC__StaticVariable_var_length, file);
#if (PERL_REVISION == 5 && PERL_VERSION >= 9)
  if (PL_unitcheckav)
       call_list(PL_scopestack_ix, PL_unitcheckav);
#endif
    XSRETURN_YES;
}

