From 11a39fe4420c9bcf095e8bb586946eb66cfa2aec Mon Sep 17 00:00:00 2001 From: Nicholas Clark Date: Wed, 7 Sep 2011 13:15:04 +0200 Subject: [PATCH] Store struct termios used by POSIX::Termios directly in the object SV. Previously POSIX::Termios was using the PTROBJ typemap to store a pointer to a dynamically-allocated struct termios as an IV (blessed into the class). This requires an explicit DESTROY to free the dynamic allocation, but fails badly if any POSIX::Termios objects exist at ithread clone time, as the dynamic allocation is not duplicated in the new thread. (DESTROY is called in both threads, free-from-wrong pool or other jollity occurs.) Removing dynamic allocation removes the need for a DESTROY method. This introduces a new OPAQUEPTROBJ typemap, but currently doesn't use the OUTPUT section, as that copies an existing structure, whereas POSIX::Termios->new() only needs to zero-allocate the right space. Assuming that this typemap should be of general applicability, it should be moved to the main typemap file. --- ext/POSIX/POSIX.xs | 28 +++++++++++++--------------- ext/POSIX/typemap | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 41f53d9..f293553 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -712,30 +712,28 @@ sigismember(sigset, sig) MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf -POSIX::Termios +void new(packname = "POSIX::Termios", ...) const char * packname CODE: { #ifdef I_TERMIOS - Newx(RETVAL, 1, struct termios); + SV *t; + ST(0) = sv_newmortal(); + t = newSVrv(ST(0), packname); + sv_grow(t, sizeof(struct termios) + 1); + SvCUR_set(t, sizeof(struct termios)); + SvPOK_on(t); + /* The previous implementation stored a pointer to an uninitialised + struct termios. Seems safer to initialise it, particularly as + this implementation exposes the struct to prying from perl-space. + */ + memset(SvPVX(t), 0, 1 + sizeof(struct termios)); + XSRETURN(1); #else not_here("termios"); - RETVAL = 0; #endif } - OUTPUT: - RETVAL - -void -DESTROY(termios_ref) - POSIX::Termios termios_ref - CODE: -#ifdef I_TERMIOS - Safefree(termios_ref); -#else - not_here("termios"); -#endif SysRet getattr(termios_ref, fd = 0) diff --git a/ext/POSIX/typemap b/ext/POSIX/typemap index d54d5d1..b283099 100644 --- a/ext/POSIX/typemap +++ b/ext/POSIX/typemap @@ -12,5 +12,19 @@ speed_t T_IV tcflag_t T_IV cc_t T_IV POSIX::SigSet T_PTROBJ -POSIX::Termios T_PTROBJ +POSIX::Termios T_OPAQUEPTROBJ POSIX::SigAction T_HVREF + +INPUT +T_OPAQUEPTROBJ + if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) { + $var = ($type)SvPV_nolen(SvRV($arg)); + } + else + Perl_croak(aTHX_ \"%s: %s is not of type %s\", + ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, + \"$var\", \"$ntype\") + +OUTPUT +T_OPAQUEPTROBJ + sv_setref_pvn($arg, \"${ntype}\", (const char*)$var, sizeof(*$var)); -- 2.7.4