Skip to content

Commit

Permalink
simplify C to python references
Browse files Browse the repository at this point in the history
  • Loading branch information
koehlma committed Jan 23, 2016
1 parent 5824f0a commit 414fa5e
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 45 deletions.
10 changes: 0 additions & 10 deletions cffi_declarations.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,16 +755,6 @@ const char* uv_err_name(int);
/* Python */
const char* PYTHON_UV_CFFI_VERSION;

typedef struct {
void* magic;
void* object;
} py_data;

void* py_attach(py_data* data, void* object);
py_data* py_detach(void* pointer);



/* Cross-Platform */
typedef struct {
uint64_t flowinfo;
Expand Down
21 changes: 1 addition & 20 deletions cffi_source.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,9 @@

#include <uv.h>

const char* PYTHON_UV_CFFI_VERSION = "__version__";


/* Python */
typedef struct {
void* magic;
void* object;
} py_data;

void* py_attach(py_data* data, void* object) {
data->magic = &py_attach;
data->object = object;
return (void*) data;
}

py_data* py_detach(void* pointer) {
if (pointer != NULL && ((py_data*) pointer)->magic == &py_attach) {
return (py_data*) pointer;
}
return NULL;
}

const char* PYTHON_UV_CFFI_VERSION = "__version__";


/* Cross-Platform */
Expand Down
4 changes: 2 additions & 2 deletions uv/handle.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Handle(object):
uv.Loop
"""

__slots__ = ['__weakref__', 'loop', 'uv_handle', 'attachment', 'on_closed',
__slots__ = ['__weakref__', 'loop', 'uv_handle', '_c_reference', 'on_closed',
'closed', 'closing', 'data', 'allocator']

def __init__(self, uv_handle, loop=None):
Expand All @@ -134,7 +134,7 @@ def __init__(self, uv_handle, loop=None):
if self.loop.closed:
raise error.ClosedLoopError()
self.uv_handle = ffi.cast('uv_handle_t*', uv_handle)
self.attachment = library.attach(self.uv_handle, self)
self._c_reference = library.attach(self.uv_handle, self)
self.on_closed = common.dummy_callback
"""
Callback which should run after the handle has been closed.
Expand Down
59 changes: 49 additions & 10 deletions uv/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import os
import sys

from collections import namedtuple

from . import __version__
Expand Down Expand Up @@ -67,16 +68,54 @@
Attachment = namedtuple('Attachment', ['c_data', 'c_reference'])


def attach(structure, instance):
attachment = Attachment(ffi.new('py_data*'), ffi.new_handle(instance))
lib.py_attach(attachment.c_data, attachment.c_reference)
structure.data = attachment.c_data
return attachment


def detach(structure):
data = lib.py_detach(structure.data)
if data: return ffi.from_handle(data.object)
def attach(c_structure, instance):
"""
Attach a python object to a C data structure's `data` field using
:func:`ffi.new_handle`. The returned reference must be stored in
order to receive the original object with :func:`detach`.
:param c_structure:
C structure with data field of type `void*`
:param instance:
python instance to attach
:type c_structure:
ffi.CData
:type instance:
object
:return:
reference of type `void*` (needs to be stored)
:rtype:
ffi.CData[void*]
"""
c_reference = ffi.new_handle(instance)
c_structure.data = c_reference
return c_reference


def detach(c_structure):
"""
Detach a python object from a C data structure's data field using
:func:`ffi.from_handle`. This might segfault on CPython if the
referenced python object or the reference itself has been garbage
collected. On PyPy it returns `None` in these cases.
:param c_structure:
C structure with data field of type `void*`
:return:
attached python instance if found
:rtype:
Optional[object]
"""
if c_structure.data:
try:
# NOTE: on CPython this might segfault if the pointer is not valid
instance = ffi.from_handle(c_structure.data)
return instance
except SystemError:
pass


def mutable_c_string(string):
Expand Down
2 changes: 1 addition & 1 deletion uv/loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ def __init__(self, allocator=None, default=False, buffer_size=2**16):

common.attach_finalizer(self, loop_finalizer, self.uv_loop)

self.attachment = library.attach(self.uv_loop, self)
self._c_reference = library.attach(self.uv_loop, self)

self.allocator = allocator or DefaultAllocator(buffer_size)

Expand Down
4 changes: 2 additions & 2 deletions uv/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ class Request(object):
:type loop: Loop
"""

__slots__ = ['uv_request', 'attachment', 'finished', 'loop']
__slots__ = ['uv_request', '_c_reference', 'finished', 'loop']

def __init__(self, uv_request, loop=None):
self.uv_request = ffi.cast('uv_req_t*', uv_request)
self.attachment = library.attach(self.uv_request, self)
self._c_reference = library.attach(self.uv_request, self)
self.loop = loop or Loop.get_current()
"""
Loop where the handle is running on.
Expand Down

0 comments on commit 414fa5e

Please sign in to comment.