Skip to content

Commit

Permalink
remove all the zero-copy shit
Browse files Browse the repository at this point in the history
  • Loading branch information
jrockway committed Dec 21, 2010
1 parent c9940ad commit 85522fe
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 118 deletions.
35 changes: 3 additions & 32 deletions RawZMQ.xs
Expand Up @@ -83,49 +83,20 @@ zmq_msg_init_data(SV *self, SV *data)
zmq_msg_t *msg;
STRLEN len;
char *buf;
zmqxs_sv_t *hint;
char *copy;
CODE:
if(!SvPOK(data))
croak("You must pass init_data an SvPV and 0x%p is not one", data);
if(SvUTF8(data))
croak("Wide character in init_data, you must encode characters");

buf = SvPV(data, len);
hint = zmqxs_new_sv(data);
ZMQ_MSG_ALLOCATE(zmq_msg_init_data(msg, buf, len, &zmqxs_free_sv, hint));
SvREFCNT_inc_simple_void_NN(data);
copy = savepvn(buf, len);
ZMQ_MSG_ALLOCATE(zmq_msg_init_data(msg, copy, len, &zmqxs_free_data, NULL));

int
zmq_msg_size(zmq_msg_t *msg)

int
zmq_msg_data_nocopy(SV *self, SV *sv)
PREINIT:
char *buf;
size_t len;
zmq_msg_t *msg;
CODE:
msg = xs_object_magic_get_struct(aTHX_ SvRV(self));
if(!msg)
croak("Invalid call to zmq_msg_data: no zmq_msg_t attached");

len = zmq_msg_size(msg);
if(len > 0){
buf = zmq_msg_data(msg);
/* printf("debug: sharing buf at %p\n", buf); */
SvUPGRADE(sv, SVt_PV);
SvPV_set(sv, buf);
SvCUR_set(sv, len);
SvLEN_set(sv, len);
SvPOK_on(sv);
SvREADONLY_on(sv);
/* make buf stay alive as long as sv is alive */
zmqxs_ref_sv(sv, self);
RETVAL = len;
}
OUTPUT:
RETVAL

SV *
zmq_msg_data(zmq_msg_t *msg)
PREINIT:
Expand Down
25 changes: 0 additions & 25 deletions t/message.t
Expand Up @@ -2,7 +2,6 @@ use strict;
use warnings;
use Test::More;
use Test::Exception;
use Devel::Peek qw(Dump SvREFCNT);

use ZeroMQ::Raw;

Expand Down Expand Up @@ -40,39 +39,15 @@ use ZeroMQ::Raw;
# new from scalar
{
my $scalar = "foo bar";
is SvREFCNT($scalar), 1, 'baseline refcnt';

my $from_scalar;
lives_ok {
$from_scalar = ZeroMQ::Raw::Message->new_from_scalar($scalar);
} 'creating msg from scalar works';

is SvREFCNT($scalar), 2, 'refcnt increased ok';

ok $from_scalar->is_allocated, 'allocated ok';
is $from_scalar->size, 7, 'got correct size';
is $from_scalar->data, 'foo bar', 'got correct data';

is SvREFCNT($from_scalar), 1, 'message has refcnt of 1';
{
# test zero-copy
my $not_copied;
$from_scalar->data_nocopy($not_copied);
is $not_copied, 'foo bar', 'got correct data';
is SvREFCNT($from_scalar), 2, 'message gets refcnt++';

# changing scalar changes not_copied
$scalar =~ s/foo/goo/;

is $not_copied, 'goo bar', 'got new data (!)';
}
is SvREFCNT($from_scalar), 1, 'data non-copy goes away, message refcnt--';

lives_ok {
undef $from_scalar;
} 'undef $from_scalar lives ok';

is SvREFCNT($scalar), 1, 'refcnt decremented when message went away';
}

{
Expand Down
50 changes: 2 additions & 48 deletions zmqxs.c
Expand Up @@ -8,23 +8,8 @@ inline void Zmqxs_set_bang(pTHX_ int err){
sv_setsv(errsv, newSViv(err));
}

zmqxs_sv_t *Zmqxs_new_sv(pTHX_ SV *sv) {
zmqxs_sv_t *hint;
Newx(hint, 1, zmqxs_sv_t);
if(hint == NULL)
croak("Problem allocating SV hint struct");
hint->perl = PERL_GET_CONTEXT;
hint->sv = sv;
return hint;
}

void zmqxs_free_sv(void *data, void *hint) {
/* printf("debug: freeing data at %p, given SvPV with pointer at %p\n",
data, SvPV_nolen((SV *) hint)); */
zmqxs_sv_t *h = hint;
PerlInterpreter *my_perl = h->perl;
SvREFCNT_dec((SV *) h->sv);
Safefree(h);
void zmqxs_free_data(void *data, void *hint) {
Safefree(data);
}

int Zmqxs_has_object(pTHX_ SV *self){
Expand Down Expand Up @@ -56,34 +41,3 @@ inline void Zmqxs_msg_finish_allocate(pTHX_ SV *self, int status, zmq_msg_t *msg
}
xs_object_magic_attach_struct(aTHX_ SvRV(self), msg);
}

/* magic for a SvPV whose buffer is owned by another SV */

STATIC MGVTBL ref_mg_vtbl = {
NULL, /* get */
NULL, /* set */
NULL, /* len */
NULL, /* clear */
Zmqxs_ref_mg_free, /* free */
#if MGf_COPY
NULL, /* copy */
#endif /* MGf_COPY */
#if MGf_DUP
NULL, /* dup */
#endif /* MGf_DUP */
#if MGf_LOCAL
NULL, /* local */
#endif /* MGf_LOCAL */
};

int Zmqxs_ref_mg_free(pTHX_ SV *sv, MAGIC* mg){
/* printf("debug: decrementing refcnt on SV %p attached to %p\n",
mg->mg_ptr, sv); */
SvREFCNT_dec( (SV *) mg->mg_ptr);
}

void Zmqxs_ref_sv(pTHX_ SV *sv, SV *ptr){
/* printf("debug: attaching magical magic to %p (refs %p)\n", sv, ptr); */
SvREFCNT_inc_simple_void_NN(ptr);
sv_magicext(sv, NULL, PERL_MAGIC_ext, &ref_mg_vtbl, (void *) ptr, 0 );
}
14 changes: 1 addition & 13 deletions zmqxs.h
Expand Up @@ -15,14 +15,7 @@ typedef void zmq_ctx_t;
typedef void zmq_sock_t;
typedef int zmq_sock_err; /* for the typemap */

/* tell zmq how to deref SVs */
typedef struct {
PerlInterpreter *perl;
SV *sv;
} zmqxs_sv_t;

zmqxs_sv_t *Zmqxs_new_sv(pTHX_ SV *);
void zmqxs_free_sv(void *, void *);
void zmqxs_free_data(void *, void *);

/* convenient macro for updating $! */
#define SET_BANG Zmqxs_set_bang(aTHX_ _ERRNO)
Expand All @@ -36,13 +29,8 @@ inline void Zmqxs_ensure_unallocated(pTHX_ SV *);
inline zmq_msg_t *Zmqxs_msg_start_allocate(pTHX_ SV *);
inline void Zmqxs_msg_finish_allocate(pTHX_ SV *, int, zmq_msg_t *);

/* magic that lets one object refcnt++ another (and -- when freed)*/
int Zmqxs_ref_mg_free(pTHX_ SV *, MAGIC *);
void Zmqxs_ref_sv(pTHX_ SV *, SV *);

#define zmqxs_new_sv(a) Zmqxs_new_sv(aTHX_ a)
#define zmqxs_has_object(a) Zmqxs_has_object(aTHX_ a)
#define zmqxs_ensure_unallocated(a) Zmqxs_ensure_unallocated(aTHX_ a)
#define zmqxs_ref_sv(a,b) Zmqxs_ref_sv(aTHX_ a,b)

#endif

0 comments on commit 85522fe

Please sign in to comment.