From 84616652ed8622f987ada764613d84bdf4e42c7b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 8 Aug 2016 23:23:55 +0200 Subject: ... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/libcoopgamma.py | 29 ++++++++++--- src/libcoopgamma_native.pyx.gpp | 92 +++++++++++++++++++++++++++++++++++++++++ 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 = libcoopgamma_async_context_unmarshal(this, buf, &ret1) return (ret0, 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 = 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 = address + if libcoopgamma_set_nonblocking(ctx, (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 = 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 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 = address + cdef libcoopgamma_async_context_t* pends + cdef size_t selected = 0 + pends = malloc(n * sizeof(*pends)) + if pends is None: + pass + for i in range(len(pending)): + pends[i] = *pendings[i] + if libcoopgamma_synchronise(ctx, pends, len(pending), &selected) < 0: + return (False, int(errno)) + return (True, 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(address) + -- cgit v1.2.3-70-g09d2