Changeset - 952d4edf0cbb
[Not reviewed]
0 3 6
sirkibsirkib - 5 years ago 2020-02-08 10:35:58
christopher.esterhuyse@gmail.com
first C example
9 files changed with 201 insertions and 45 deletions:
0 comments (0 inline, 0 general)
examples/0_forward/alice.c
Show inline comments
 
new file 100644
 
#include <stdio.h>
 
#include <string.h>
 
#include "../../reowolf.h"
 

	
 
int main() {
 
	// ALICE
 
	
 
	char* pdl ="\
 
	primitive forward(in i, out o) {\
 
		while(true) synchronous {\
 
			put(o, get(i));\
 
		}\
 
	}";
 
	
 
	
 
	char msg_buf[128];
 
	memset(msg_buf, 0, 128);
 
	
 
	printf("input a message to send:");
 
	if (fgets(msg_buf, 128-1, stdin) == NULL) {
 
		printf("LINE READ BAD\n");
 
		return 1;
 
	}
 
	int msg_len = strlen(msg_buf);
 
	msg_buf[msg_len-1] = 0;
 
	printf("sending msg `%s`\n", msg_buf);
 
	
 
	Connector* c = connector_new();
 
	if (connector_configure(c, pdl, "forward")) {
 
		printf("CONFIG FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	if (connector_bind_native(c, 0)) {
 
		printf("BIND0 FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	if (connector_bind_passive(c, 1, "127.0.0.1:7000")) {
 
		printf("BIND1 FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	printf("connecting... \n");
 
	if (connector_connect(c, 10000)) {
 
		printf("CONNECT FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	
 
	int i;
 
	for (i = 0; i < 3; i++) {
 
		if (connector_put(c, 0, msg_buf, msg_len)) {
 
			printf("CONNECT PUT: %s\n", connector_error_peek());
 
			return 1;
 
		}
 
		if (connector_sync(c, 10000)) {
 
			printf("SYNC FAILED: %s\n", connector_error_peek());
 
			return 1;
 
		}
 
		printf("SEND OK\n");
 
	}
 
	
 
	printf("OK\n");
 
	connector_destroy(c);
 
	return 0;
 
}
 
\ No newline at end of file
examples/0_forward/alice.exe
Show inline comments
 
new file 100644
 
binary diff not shown
examples/0_forward/bob.c
Show inline comments
 
new file 100644
 
#include <stdio.h>
 
#include "../../reowolf.h"
 

	
 
int main() {
 
	
 
	char* pdl ="\
 
	primitive forward(in i, out o) {\
 
		while(true) synchronous {\
 
			put(o, get(i));\
 
		}\
 
	}";
 
	
 
	// BOB
 
	Connector* c = connector_new();
 
	if (connector_configure(c, pdl, "forward")) {
 
		printf("CONFIG FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	if (connector_bind_active(c, 0, "127.0.0.1:7000")) {
 
		printf("BIND0 FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	if (connector_bind_native(c, 1)) {
 
		printf("BIND1 FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	printf("connecting... \n");
 
	if (connector_connect(c, 10000)) {
 
		printf("CONNECT FAILED: %s\n", connector_error_peek());
 
		return 1;
 
	}
 
	
 
	int i;
 
	for (i = 0; i < 3; i++) {
 
		if (connector_get(c, 0)) {
 
			printf("CONNECT GET: %s\n", connector_error_peek());
 
			return 1;
 
		}
 
		if (connector_sync(c, 10000)) {
 
			printf("SYNC FAILED: %s\n", connector_error_peek());
 
			return 1;
 
		}
 
		int msg_len;
 
		const unsigned char * msg;
 
		if (connector_gotten(c, 0, &msg, &msg_len)) {
 
			printf("READ FAILED: %s\n", connector_error_peek());
 
			return 1;
 
		}
 
		printf("received: `%s`\n", msg);
 
	}
 
	
 
	printf("OK\n");
 
	connector_destroy(c);
 
	return 0;
 
}
 
\ No newline at end of file
examples/0_forward/bob.exe
Show inline comments
 
new file 100644
 
binary diff not shown
examples/0_forward/make.sh
Show inline comments
 
new file 100644
 
echo "MAKING!"
 
gcc main.c -L ../../target/release -lreowolf_rs -o main
 
echo "DONE!"
examples/0_forward/reowolf_rs.dll
Show inline comments
 
new file 100644
 
binary diff not shown
reowolf.h
Show inline comments
 
@@ -9,101 +9,139 @@
 
#include <stdlib.h>
 

	
 
typedef struct Connector Connector;
 

	
 
typedef uint32_t ControllerId;
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "active":
 
 * (The port will conenct to a "passive" port at the given address during connect())
 
 * Returns:
 
 * - 0 for success
 
 * - 1 if the port was already bound and was left unchanged
 
 * # Safety
 
 * TODO
 
 */
 
int connector_bind_active(Connector *connector, unsigned int proto_port_index, const char *address);
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "native":
 
 * (The port is exposed for reading and writing from the application)
 
 * Returns:
 
 * # Safety
 
 * TODO
 
 */
 
int connector_bind_native(Connector *connector, uintptr_t proto_port_index);
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "native":
 
 * (The port is exposed for reading and writing from the application)
 
 * Returns:
 
 * # Safety
 
 * TODO
 
 */
 
int connector_bind_passive(Connector *connector,
 
                           unsigned int proto_port_index,
 
                           const char *address);
 

	
 
/**
 
 * Configures the given Reowolf connector with a protocol description in PDL.
 
 * Returns:
 
 * # Safety
 
 * TODO
 
 */
 
int connector_configure(Connector *connector, char *pdl);
 
int connector_configure(Connector *connector, char *pdl, char *main);
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "active":
 
 * (The port will conenct to a "passive" port at the given address during connect())
 
 * Returns:
 
 * - 0 SUCCESS: connected successfully
 
 * - TODO error codes
 
 * # Safety
 
 * TODO
 
 */
 
int connector_connect(Connector *connector, uint64_t timeout_millis);
 

	
 
/**
 
 * Destroys the given connector, freeing its underlying resources.
 
 * # Safety
 
 * TODO
 
 */
 
void connector_destroy(Connector *connector);
 

	
 
/**
 
 * Resets the error message buffer.
 
 * Returns:
 
 * - 0 if an error was cleared
 
 * - 1 if there was no error to clear
 
 * # Safety
 
 * TODO
 
 */
 
int connector_error_clear(void);
 

	
 
/**
 
 * Returns a pointer into the error buffer for reading as a null-terminated string
 
 * Returns null if there is no error in the buffer.
 
 * # Safety
 
 * TODO
 
 */
 
const char *connector_error_peek(void);
 

	
 
/**
 
 * Creates and returns Reowolf Connector structure allocated on the heap.
 
 * Prepares to synchronously put a message at the given port, writing it to the given buffer.
 
 * - 0 SUCCESS
 
 * - 1 this port has the wrong direction
 
 * - 2 this port is already marked to get
 
 * # Safety
 
 * TODO
 
 */
 
Connector *connector_new(void);
 
int connector_get(Connector *connector, unsigned int proto_port_index);
 

	
 
int connector_next_batch(Connector *connector);
 

	
 
int connector_sync(Connector *connector, uint64_t timeout_millis);
 
/**
 
 * # Safety
 
 * TODO
 
 */
 
int connector_gotten(Connector *connector,
 
                     unsigned int proto_port_index,
 
                     const unsigned char **buf_ptr_outptr,
 
                     unsigned int *len_outptr);
 

	
 
/**
 
 * Creates and returns Reowolf Connector structure allocated on the heap.
 
 */
 
Connector *connector_with_controller_id(ControllerId controller_id);
 
Connector *connector_new(void);
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "active":
 
 * (The port will conenct to a "passive" port at the given address during connect())
 
 * Returns:
 
 * - 0 for success
 
 * - 1 if the port was already bound and was left unchanged
 
 * # Safety
 
 * TODO
 
 */
 
int port_bind_active(Connector *connector, unsigned int proto_port_index, const char *address);
 
int connector_next_batch(Connector *connector);
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "native":
 
 * (The port is exposed for reading and writing from the application)
 
 * Returns:
 
 * Prepares to synchronously put a message at the given port, reading it from the given buffer.
 
 * # Safety
 
 * TODO
 
 */
 
int port_bind_native(Connector *connector, uintptr_t proto_port_index);
 
int connector_put(Connector *connector,
 
                  unsigned int proto_port_index,
 
                  unsigned char *buf_ptr,
 
                  unsigned int msg_len);
 

	
 
/**
 
 * Provides a binding annotation for the port with the given index with "native":
 
 * (The port is exposed for reading and writing from the application)
 
 * Returns:
 
 * # Safety
 
 * TODO
 
 */
 
int port_bind_passive(Connector *connector, unsigned int proto_port_index, const char *address);
 

	
 
int port_close(Connector *connector, unsigned int _proto_port_index);
 
int connector_sync(Connector *connector, uint64_t timeout_millis);
 

	
 
/**
 
 * Prepares to synchronously put a message at the given port, writing it to the given buffer.
 
 * - 0 SUCCESS
 
 * - 1 this port has the wrong direction
 
 * - 2 this port is already marked to get
 
 * Creates and returns Reowolf Connector structure allocated on the heap.
 
 */
 
int port_get(Connector *connector, unsigned int proto_port_index);
 
Connector *connector_with_controller_id(ControllerId controller_id);
 

	
 
/**
 
 * Prepares to synchronously put a message at the given port, reading it from the given buffer.
 
 * # Safety
 
 * TODO
 
 */
 
int port_put(Connector *connector,
 
             unsigned int proto_port_index,
 
             unsigned char *buf_ptr,
 
             unsigned int msg_len);
 

	
 
int read_gotten(Connector *connector,
 
                unsigned int proto_port_index,
 
                const unsigned char **buf_ptr_outptr,
 
                unsigned int *len_outptr);
 
int port_close(Connector *connector, unsigned int _proto_port_index);
 

	
 
#endif /* REOWOLF_HEADER_DEFINED */
src/runtime/endpoint.rs
Show inline comments
 
@@ -125,16 +125,13 @@ impl Endpoint {
 
                'read_loop: loop {
 
                    use std::io::Read;
 
                    match stream.read_to_end(inbox) {
 
                        Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => break 'read_loop,
 
                        Ok(0) => break 'read_loop,
 
                        Ok(_) => (),
 
                        Err(e) => {
 
                            println!("BAD IS {:?}", e);
 
                            panic!("BAD");
 
                        }
 
                        Err(_e) => return Err(EndpointErr::Disconnected),
 
                    }
 
                }
 
                use crate::runtime::serde::{De, MonitoredReader};
 
                let mut monitored = MonitoredReader::from(&inbox[..]);
 
                match De::<Msg>::de(&mut monitored) {
 
                    Ok(msg) => {
src/runtime/ffi.rs
Show inline comments
 
@@ -248,13 +248,13 @@ pub unsafe extern "C" fn connector_destroy(connector: *mut Connector) {
 
}
 

	
 
/// Prepares to synchronously put a message at the given port, reading it from the given buffer.
 
/// # Safety
 
/// TODO
 
#[no_mangle]
 
pub unsafe extern "C" fn port_put(
 
pub unsafe extern "C" fn connector_put(
 
    connector: *mut Connector,
 
    proto_port_index: c_uint,
 
    buf_ptr: *mut c_uchar,
 
    msg_len: c_uint,
 
) -> c_int {
 
    let buf = std::slice::from_raw_parts_mut(buf_ptr, msg_len.try_into().unwrap());
 
@@ -275,13 +275,13 @@ pub unsafe extern "C" fn port_put(
 
/// - 0 SUCCESS
 
/// - 1 this port has the wrong direction
 
/// - 2 this port is already marked to get
 
/// # Safety
 
/// TODO
 
#[no_mangle]
 
pub unsafe extern "C" fn port_get(connector: *mut Connector, proto_port_index: c_uint) -> c_int {
 
pub unsafe extern "C" fn connector_get(connector: *mut Connector, proto_port_index: c_uint) -> c_int {
 
    let mut b = Box::from_raw(connector); // unsafe!
 
    let ret = b.get(proto_port_index.try_into().unwrap());
 
    Box::into_raw(b); // don't drop!
 
                      // use PortOperationErr::*;
 
    match ret {
 
        Ok(()) => 0,
 
@@ -292,13 +292,13 @@ pub unsafe extern "C" fn port_get(connector: *mut Connector, proto_port_index: c
 
    }
 
}
 

	
 
/// # Safety
 
/// TODO
 
#[no_mangle]
 
pub unsafe extern "C" fn read_gotten(
 
pub unsafe extern "C" fn connector_gotten(
 
    connector: *mut Connector,
 
    proto_port_index: c_uint,
 
    buf_ptr_outptr: *mut *const c_uchar,
 
    len_outptr: *mut c_uint,
 
) -> c_int {
 
    let b = Box::from_raw(connector); // unsafe!
0 comments (0 inline, 0 general)