Spread

 view release on metacpan or  search on metacpan

Spread.xs  view on Meta::CPAN

}

MODULE = Spread	PACKAGE = Spread	PREFIX = GC_

REQUIRE:	1.9505
PROTOTYPES:	DISABLE

BOOT:
	/* Check version of Spread == 3.11 */
	{
        int major, minor, patch;
	if(SP_version(&major, &minor, &patch) <= 0 ||
	   major<3 || (major==3 && minor<15) ||
	   (major==3 && minor==15 && patch<1))
	  croak("%s", SPversionstr()) ; 

	{
	  SV * sperror_sv = perl_get_sv(SPERRNO, GV_ADDMULTI) ;
	  sv_setiv(sperror_sv, 0) ;
	  sv_setpv(sperror_sv, "") ;
	  SvIOK_on(sperror_sv) ;
	}
	}
	sv_NULL = newSVpv("", 0) ;

double
constant(name,arg)
        char *          name
        int             arg

#define GC_version() SPversionstr()
char *
GC_version()

SV *
GC_disconnect(svmbox)
	SV * svmbox
	CODE:
	{
	  int mbox = SvIV(svmbox);
	  if((mbox = SP_disconnect(mbox))==0)
	    RETVAL = &PL_sv_yes;
	  else {
	    SetSpErrorNo(mbox);
	    RETVAL = &PL_sv_no;
	  }
	}
	OUTPUT:
	  RETVAL

AV *
GC_connect_i(rv)
	SV * rv
	PREINIT:
	  SV *MAILBOX, *PRIVATE_GROUP;
	  SV **afetch;
	  int i, error, pr, gm;
	  mailbox mbox = -1;
	  char *sn, *pn, pg[MAX_GROUP_NAME];
	  HV *hv;
	PPCODE:
	  MAILBOX = PRIVATE_GROUP = &PL_sv_undef;
	  if(!SvROK(rv) || SvTYPE(hv = (HV *)SvRV(rv))!=SVt_PVHV)
	    croak("not a HASH reference");
	  for(i=0;i<nconnect_params;i++)
	    if(hv_exists(hv, connect_params[i],
		strlen(connect_params[i])) == FALSE) {
	      SetSpErrorNo(ARGS_INSUFF);
	      goto ending;
            }
	  i=0;
	  afetch = hv_fetch(hv, connect_params[i],
		strlen(connect_params[i]), FALSE); i++;
	  sn = SvPV(*afetch, PL_na);
	  afetch = hv_fetch(hv, connect_params[i],
		strlen(connect_params[i]), FALSE); i++;
	  pn = SvPV(*afetch, PL_na);
	  afetch = hv_fetch(hv, connect_params[i],
		strlen(connect_params[i]), FALSE); i++;
	  pr = SvIV(*afetch);
	  afetch = hv_fetch(hv, connect_params[i],
		strlen(connect_params[i]), FALSE); i++;
	  gm = SvIV(*afetch);
	  if((error = SP_connect(sn,pn,pr,gm,&mbox,pg))>0 && mbox>0) {
	    MAILBOX = sv_2mortal(newSViv(mbox));
	    PRIVATE_GROUP = sv_2mortal(newSVpv(pg, 0));
          } else {
	    SetSpErrorNo(error);
	  }
	ending:
          EXTEND(SP, 2);
          PUSHs(MAILBOX);
          PUSHs(PRIVATE_GROUP);

SV *
GC_join(svmbox, group_name)
	SV * svmbox
	char *group_name
	CODE:
	{
	  int mbox = SvIV(svmbox);
	  if((mbox = SP_join(mbox, group_name))==0) {
	    RETVAL = &PL_sv_yes;
	  } else {
	    SetSpErrorNo(mbox);
	    RETVAL = &PL_sv_no;
	  }
	}
	OUTPUT:
	  RETVAL

SV *
GC_leave(svmbox, group_name)
	SV * svmbox
	char *group_name
	CODE:
	{
	  int mbox = SvIV(svmbox);
	  if((mbox = SP_leave(mbox, group_name))==0) {
	    RETVAL = &PL_sv_yes;
	  } else {

Spread.xs  view on Meta::CPAN

		size_t slength;
		SV **afetch = av_fetch(groups, i, FALSE);
		string = SvPV(*afetch, slength);
		strncpy(&groupnames[i*MAX_GROUP_NAME],
			string,
			MAX_GROUP_NAME);
	      }
	    } else if(SvTYPE(group = SvRV(svgroups))==SVt_PV) {
	      groupname = SvPV(group, PL_na);
	    } else {
	      croak("not a SCALAR or ARRAY reference.");
	    }
	  } else if(groupname=SvPV(svgroups, PL_na)) {
	    group = svgroups;
	  } else {
	    SetSpErrorNo(ARGS_INSUFF);
	    goto multi_ending;
	  }

	  message = SvPV(mess, mlength);
	  if(group != NULL) {
	    /* groupname is already set and
	       we are multicasting to a single group */
	    ret = SP_multicast(mbox, stype, groupname,
				mtype, mlength, message);
	  } else if(groups != NULL) {
	    /* groupnames is already set and
	       we are multicasting to a multigroup */
	    ret = SP_multigroup_multicast(mbox, stype, ngroups,
				groupnames,
				mtype, mlength, message);
	  } else {
	    /* Something went horrbily wrong */
	    croak("not SCALAR, SCALAR ref or ARRAY ref.");
	  }
	  if(ret<0)
	    SetSpErrorNo(ret);
	  else
	    RETVAL = newSViv(ret);
	}
	multi_ending:
	OUTPUT:
	  RETVAL

AV *
GC_receive(svmbox, svtimeout=&PL_sv_undef)
	SV * svmbox
	SV * svtimeout
	PREINIT:
	  static int oldgsize=0, newgsize=(1<<6);
	  static int oldmsize=0, newmsize=(1<<15); /* 65k */
	  int i, mbox, endmis, ret, ngrps, msize;
	  int16 mtype;
	  service stype = 0;
	  struct timeval towait;
	  static char *groups=NULL;
	  static char *mess=NULL;
	  char sender[MAX_GROUP_NAME];
	  SV *STYPE, *MTYPE, *MESSAGE, *SENDER, *ENDMIS, *ERROR;
	  AV *GROUPS=(AV *)&PL_sv_undef;
	PPCODE:
	  if(svmbox == &PL_sv_undef) {
	    STYPE=SENDER=MTYPE=ENDMIS=MESSAGE=&PL_sv_undef;
	    SetSpErrorNo(ILLEGAL_SESSION);
	    goto rec_ending;
	  }
	  mbox = SvIV(svmbox);
	  ERROR=&PL_sv_undef;
	  if(svtimeout != &PL_sv_undef) {
	    double timeout;
	    fd_set readfs;
	    towait.tv_sec = 0L;
	    towait.tv_usec = 0L;
	    timeout = SvNV(svtimeout);
	    towait.tv_sec = (unsigned long)timeout;
	    towait.tv_usec =
	      (unsigned long)(1000000.0*(timeout-(double)towait.tv_sec));
	    FD_ZERO(&readfs); FD_SET(mbox, &readfs);
	    if((ret = select(mbox+1, &readfs, NULL, &readfs, &towait))!=1) {
	      STYPE=SENDER=MTYPE=ENDMIS=MESSAGE=&PL_sv_undef;
	      SetSpErrorNo( ret == 0 ? SELECT_TIMEOUT : SELECT_FAILED );
	      goto rec_ending;
	    }
	  }
       try_again:
	  /* realloc or alloc buffer if necessary */
	  if(oldgsize != newgsize) {
	    if(groups)
	      Renew(groups, newgsize*MAX_GROUP_NAME, char);
	    else
	      New(0, groups, newgsize*MAX_GROUP_NAME, char);
	    oldgsize=newgsize;
	  }
	  if(oldmsize != newmsize) {
	    if(mess)
	      Renew(mess, newmsize, char);
	    else
	      New(0, mess, newmsize, char);
	    oldmsize=newmsize;
	  }
	  if((ret=SP_receive(mbox, &stype, sender, newgsize, &ngrps, groups,
		&mtype, &endmis, newmsize, mess))<0) {
		if(ret==BUFFER_TOO_SHORT) {
		  /* Lets double it, so this won't happen again */
		  newmsize=-endmis;
		  ERROR = newSViv(BUFFER_TOO_SHORT);
		  msize = oldmsize;
		  goto try_again;
#ifdef GROUPS_TOO_SHORT
		} else if (ret==GROUPS_TOO_SHORT) {
		  newgsize=-ngrps;
		  ERROR = newSViv(GROUPS_TOO_SHORT);
		  ngrps = oldgsize;
		  goto try_again;
#endif
		} else {
		  STYPE=SENDER=MTYPE=ENDMIS=MESSAGE=&PL_sv_undef;
		  SetSpErrorNo(ret);
		}
	  } else {
	    msize=ret;



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