aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcoopgamma.py29
-rw-r--r--src/libcoopgamma_native.pyx.gpp92
2 files changed, 116 insertions, 5 deletions
diff --git a/src/libcoopgamma.py b/src/libcoopgamma.py
index 31f5aaa..9aae31b 100644
--- a/src/libcoopgamma.py
+++ b/src/libcoopgamma.py
@@ -596,7 +596,14 @@ class Context:
@param method:int|str? The adjustment method, `None` for automatic
@param site:str? The site, `None` for automatic
'''
- pass
+ if method is not None and isinstance(method, int):
+ method = str(method)
+ error = libcoopgamma_native_connect(method, site, self.address)
+ if error is not None:
+ if errno == 0:
+ pass # TODO server failed to initialise
+ else:
+ pass # TODO
def detach(self):
'''
@@ -625,7 +632,9 @@ class Context:
@param nonblocking:bool Nonblocking mode?
'''
- pass
+ error = libcoopgamma_native.libcoopgamma_native_set_nonblocking(self.address, nonbreaking)
+ if error != 0:
+ pass # TODO
def flush(self):
'''
@@ -635,7 +644,9 @@ class Context:
with EINTR, call this function to complete the transfer. The `async` parameter
will always be in a properly configured state if a function fails with EINTR.
'''
- pass
+ error = libcoopgamma_native.libcoopgamma_native_flush(self.address)
+ if error != 0:
+ pass # TODO
def synchronise(self, pending : list) -> int:
'''
@@ -651,13 +662,21 @@ class Context:
`None` if the message is ignored, which happens if
corresponding AsyncContext is not listed.
'''
- pass
+ pending = [p.address for p in pending]
+ (successful, value) = libcoopgamma_native.libcoopgamma_native_flush(self.address, pending)
+ if not successful:
+ if error == 0:
+ return None
+ else:
+ pass # TODO
+ else:
+ return value
def skip_message(self):
'''
Tell the library that you will not be parsing a receive message
'''
- pass
+ libcoopgamma_native.libcoopgamma_native_skip_message(self.address)
def get_crtcs_send(self) -> AsyncContext:
'''
diff --git a/src/libcoopgamma_native.pyx.gpp b/src/libcoopgamma_native.pyx.gpp
index 73d8353..b28c57b 100644
--- a/src/libcoopgamma_native.pyx.gpp
+++ b/src/libcoopgamma_native.pyx.gpp
@@ -1043,3 +1043,95 @@ def libcoopgamma_native_async_context_unmarshal(buf : bytes):
ret0 = <int>libcoopgamma_async_context_unmarshal(this, <bytes>buf, &ret1)
return (ret0, <int>ret1)
+
+def libcoopgamma_native_connect(method : str, site : str, address : int):
+ '''
+ Connect to a coopgamma server, and start it if necessary
+
+ Use `libcoopgamma_context_destroy` to disconnect
+
+ SIGCHLD must not be ignored or blocked
+
+ @param method:str? The adjustment method, `NULL` for automatic
+ @param site:str? The site, `NULL` for automatic
+ @param address:int The address of the state of the library, must be initialised
+ @return :int? `None`, 0 if the server on could not be initialised,
+ the value `errno` on other errors
+ '''
+ cdef libcoopgamma_context_t* ctx = <libcoopgamma_context_t*><void*><intptr_t>address
+ if libcoopgamma_connect(method, site, ctx) < 0:
+ return int(errno)
+ return None
+
+
+def libcoopgamma_native_set_nonblocking(address : int, nonblocking : bool):
+ '''
+ By default communication is blocking, this function
+ can be used to switch between blocking and nonblocking
+
+ After setting the communication to nonblocking,
+ `libcoopgamma_flush`, `libcoopgamma_synchronise` and
+ and request-sending functions can fail with EAGAIN and
+ EWOULDBLOCK. It is safe to continue with `libcoopgamma_flush`
+ (for `libcoopgamma_flush` it selfand equest-sending functions)
+ or `libcoopgamma_synchronise` just like EINTR failure.
+
+ @param address:int The address of the state of the library, must be connected
+ @param nonblocking:bool Nonblocking mode?
+ @return :int Zero on success, the value of `errno` on error
+ '''
+ cdef libcoopgamma_context_t* ctx = <libcoopgamma_context_t*><void*><intptr_t>address
+ if libcoopgamma_set_nonblocking(ctx, <int>(1 if nonblocking else 0)) < 0:
+ return int(errno)
+ return 0
+
+
+def libcoopgamma_native_flush(address : int):
+ '''
+ Send all pending outbound data
+
+ If this function or another function that sends a request
+ to the server fails with EINTR, call this function to
+ complete the transfer. The `async` parameter will always
+ be in a properly configured state if a function fails
+ with EINTR.
+
+ @param address:int The address of the state of the library, must be connected
+ @return :int Zero on success, the value of `errno` on error
+ '''
+ cdef libcoopgamma_context_t* ctx = <libcoopgamma_context_t*><void*><intptr_t>address
+ if libcoopgamma_flush(ctx) < 0:
+ return int(errno)
+ return 0
+
+
+def libcoopgamma_native_synchronise(address : int, pending : list):
+ '''
+ Wait for the next message to be received
+
+ @param address:int The address of the state of the library, must be connected
+ @param pending:list<int> Addresses of the information for each pending request
+ @return :(:bool, :int) If [0] = 0: [1] is the value of `errno`
+ [0] = 1: [1] is the selected request
+ '''
+ cdef libcoopgamma_context_t* ctx = <libcoopgamma_context_t*><void*><intptr_t>address
+ cdef libcoopgamma_async_context_t* pends
+ cdef size_t selected = 0
+ pends = <libcoopgamma_async_context_t*>malloc(n * sizeof(*pends))
+ if pends is None:
+ pass
+ for i in range(len(pending)):
+ pends[i] = *<libcoopgamma_async_context_t*><void*><intptr_t>pendings[i]
+ if libcoopgamma_synchronise(ctx, pends, <size_t>len(pending), &selected) < 0:
+ return (False, int(errno))
+ return (True, <int>selected)
+
+
+def libcoopgamma_native_skip_message(address : int):
+ '''
+ Tell the library that you will not be parsing a receive message
+
+ @param address:int The address of the state of the library, must be connected
+ '''
+ libcoopgamma_skip_message(<libcoopgamma_context_t*><void*><intptr_t>address)
+