diff --git a/mod/box/box.h b/mod/box/box.h index d54a7868dbcb3f0e6590bcdc7868b55950f59062..7fb12efb31165d1b8dc5444be3f35782488b61ef 100644 --- a/mod/box/box.h +++ b/mod/box/box.h @@ -29,12 +29,12 @@ * SUCH DAMAGE. */ #include <util.h> -@class Port; struct txn; struct tbuf; +struct port; typedef void (*box_process_func)(struct txn *, - Port *, u32, struct tbuf *); + struct port *, u32, struct tbuf *); extern box_process_func box_process; #endif /* INCLUDES_TARANTOOL_BOX_H */ diff --git a/mod/box/box.m b/mod/box/box.m index 44714c6acbcc67eeaf4e9ff2b9eabfdcf1e4ad6d..34afed24bea60af791da6bd9b44da2a85a12c85a 100644 --- a/mod/box/box.m +++ b/mod/box/box.m @@ -48,13 +48,13 @@ #include "request.h" #include "txn.h" -static void box_process_replica(struct txn *txn, Port *port, +static void box_process_replica(struct txn *txn, struct port *port, u32 op, struct tbuf *request_data); -static void box_process_ro(struct txn *txn, Port *port, +static void box_process_ro(struct txn *txn, struct port *port, u32 op, struct tbuf *request_data); -static void box_process_ro(struct txn *txn, Port *port, +static void box_process_ro(struct txn *txn, struct port *port, u32 op, struct tbuf *request_data); -static void box_process_rw(struct txn *txn, Port *port, +static void box_process_rw(struct txn *txn, struct port *port, u32 op, struct tbuf *request_data); box_process_func box_process = box_process_ro; @@ -78,7 +78,7 @@ box_snap_row(const struct tbuf *t) } static void -box_process_rw(struct txn *txn, Port *port, +box_process_rw(struct txn *txn, struct port *port, u32 op, struct tbuf *data) { ev_tstamp start = ev_now(), stop; @@ -102,7 +102,7 @@ box_process_rw(struct txn *txn, Port *port, } static void -box_process_replica(struct txn *txn, Port *port, +box_process_replica(struct txn *txn, struct port *port, u32 op, struct tbuf *request_data) { if (!request_is_select(op)) { @@ -114,7 +114,7 @@ box_process_replica(struct txn *txn, Port *port, } static void -box_process_ro(struct txn *txn, Port *port, +box_process_ro(struct txn *txn, struct port *port, u32 op, struct tbuf *request_data) { if (!request_is_select(op)) { @@ -128,13 +128,13 @@ box_process_ro(struct txn *txn, Port *port, static void iproto_primary_port_handler(u32 op, struct tbuf *request_data) { - box_process(txn_begin(), port_iproto, op, request_data); + box_process(txn_begin(), &port_iproto, op, request_data); } static void iproto_secondary_port_handler(u32 op, struct tbuf *request_data) { - box_process_ro(txn_begin(), port_iproto, op, request_data); + box_process_ro(txn_begin(), &port_iproto, op, request_data); } static void @@ -301,7 +301,7 @@ recover_row(struct tbuf *t) u16 op = read_u16(t); struct txn *txn = txn_begin(); txn->txn_flags |= BOX_NOT_STORE; - box_process_rw(txn, port_null, op, t); + box_process_rw(txn, &port_null, op, t); } else { say_error("unknown row tag: %i", (int)tag); return -1; @@ -468,7 +468,6 @@ mod_free(void) { space_free(); memcached_free(); - port_free(); } void @@ -477,8 +476,6 @@ mod_init(void) title("loading"); atexit(mod_free); - port_init(); - /* initialization spaces */ space_init(); /* configure memcached space */ diff --git a/mod/box/box_lua.h b/mod/box/box_lua.h index 1acc1d1b3dd76e2eca76e89a52cef1f39142274c..4fd259a77eda9bd55f2369c7f949d85dfae7be47 100644 --- a/mod/box/box_lua.h +++ b/mod/box/box_lua.h @@ -36,7 +36,7 @@ struct lua_State; * (implementation of 'CALL' command code). */ @interface Call: Request -- (void) execute: (struct txn *) txn :(Port *) port; +- (void) execute: (struct txn *) txn :(struct port *) port; @end /** diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m index 89a8702e1eb6536602174c8737f600233d758c7b..893829ddc3269b13dcf7a9c59231078ae4a54e17 100644 --- a/mod/box/box_lua.m +++ b/mod/box/box_lua.m @@ -875,32 +875,11 @@ static const struct luaL_reg lbox_iterator_meta[] = { * everything into Lua stack first. * @sa iov_add_multret */ -@interface PortLua: PortNull { - struct lua_State *L; -} -+ (PortLua *) alloc; -- (id) init: (struct lua_State *) L_arg; -@end - -@implementation PortLua -+ (PortLua *) alloc -{ - size_t sz = class_getInstanceSize(self); - id new = palloca(fiber->gc_pool, sz, sizeof(void *)); - memset(new, 0, sz); - object_setClass(new, self); - return new; -} -- (id) init: (struct lua_State *) L_arg -{ - if ((self = [super init])) - L = L_arg; - return self; -} - -- (void) addTuple: (struct tuple *) tuple +static void +port_lua_add_tuple(void *data, struct tuple *tuple) { + lua_State *L = data; @try { lbox_pushtuple(L, tuple); } @catch (...) { @@ -908,7 +887,12 @@ static const struct luaL_reg lbox_iterator_meta[] = { } } -@end +struct port_vtab port_lua_vtab = { + port_null_add_u32, + port_null_dup_u32, + port_lua_add_tuple, + port_null_add_lua_multret +}; /* }}} */ @@ -945,7 +929,8 @@ static int lbox_process(lua_State *L) size_t allocated_size = palloc_allocated(fiber->gc_pool); struct txn *txn = txn_begin(); - Port *port_lua = [[PortLua alloc] init: L]; + struct port *port_lua = palloc(fiber->gc_pool, sizeof(struct port)); + port_init(port_lua, &port_lua_vtab, L); @try { box_process(txn, port_lua, op, &req); } @finally { @@ -1006,7 +991,7 @@ void box_lua_find(lua_State *L, const char *name, const char *name_end) * Invoke a Lua stored procedure from the binary protocol * (implementation of 'CALL' command code). */ -- (void) execute: (struct txn *) txn : (Port *)port +- (void) execute: (struct txn *) txn : (struct port *)port { (void) txn; lua_State *L = lua_newthread(root_L); @@ -1027,7 +1012,7 @@ void box_lua_find(lua_State *L, const char *name, const char *name_end) } lua_call(L, nargs, LUA_MULTRET); /* Send results of the called procedure to the client. */ - [port addLuaMultret: L]; + port_add_lua_multret(port, L); } @catch (tnt_Exception *e) { @throw; } @catch (...) { diff --git a/mod/box/memcached.m b/mod/box/memcached.m index 3b3c651c7db3075ba56382c2339b735ba27ca631..a490f1d31f23cc51e4476d040aabcf60889aaf83 100644 --- a/mod/box/memcached.m +++ b/mod/box/memcached.m @@ -114,7 +114,7 @@ store(void *key, u32 exptime, u32 flags, u32 bytes, u8 *data) * Use a box dispatch wrapper which handles correctly * read-only/read-write modes. */ - box_process(txn_begin(), port_null, REPLACE, req); + box_process(txn_begin(), &port_null, REPLACE, req); } static void @@ -129,7 +129,7 @@ delete(void *key) tbuf_append(req, &key_len, sizeof(key_len)); tbuf_append_field(req, key); - box_process(txn_begin(), port_null, DELETE, req); + box_process(txn_begin(), &port_null, DELETE, req); } static struct tuple * @@ -277,7 +277,7 @@ void memcached_get(size_t keys_count, struct tbuf *keys, stats.get_hits++; stat_collect(stat_base, MEMC_GET_HIT, 1); - fiber_ref_tuple(tuple); + iov_ref_tuple(tuple); if (show_cas) { struct tbuf *b = tbuf_alloc(fiber->gc_pool); diff --git a/mod/box/port.h b/mod/box/port.h index 87491bfc1c3ff2bca7f1f247cc8aa4113452a7c8..b4184fa43cd9264f58fae747cdfb82762fce8f07 100644 --- a/mod/box/port.h +++ b/mod/box/port.h @@ -29,38 +29,78 @@ * SUCH DAMAGE. */ #include <util.h> -#import "object.h" struct tuple; struct lua_State; -@interface Port: tnt_Object -- (void) addU32: (u32 *) u32; -- (void) dupU32: (u32) u32; -- (void) addTuple: (struct tuple *) tuple; -- (void) addLuaMultret: (struct lua_State *) L; -@end +struct port_vtab +{ + u32* (*add_u32)(void *data); + void (*dup_u32)(void *data, u32 num); + void (*add_tuple)(void *data, struct tuple *tuple); + void (*add_lua_multret)(void *data, struct lua_State *L); +}; -@interface PortNull: Port -@end +struct port +{ + struct port_vtab *vtab; + void *data; +}; /** * A hack to keep tuples alive until iov_flush(fiber->iovec). * Is internal to port_iproto implementation, but is also - * used in memcached.m, which doesn't uses fiber->iovec - * bypassing port_iproto a public declaration here. + * used in memcached.m, which doesn't use fiber->iovec. */ -void fiber_ref_tuple(struct tuple *tuple); +void iov_ref_tuple(struct tuple *tuple); + +/** Create a port instance. */ +static inline void +port_init(struct port *port, struct port_vtab *vtab, void *data) +{ + port->vtab = vtab; + port->data = data; +} + +static inline u32* +port_add_u32(struct port *port) +{ + return (port->vtab->add_u32)(port->data); +} + +static inline void +port_dup_u32(struct port *port, u32 num) +{ + (port->vtab->dup_u32)(port->data, num); +} + +static inline void +port_add_tuple(struct port *port, struct tuple *tuple) +{ + (port->vtab->add_tuple)(port->data, tuple); +} + +static inline void +port_add_lua_multret(struct port *port, struct lua_State *L) +{ + (port->vtab->add_lua_multret)(port->data, L); +} +/** Reused in port_lua */ +u32* +port_null_add_u32(void *data __attribute__((unused))); + +void +port_null_dup_u32(void *data __attribute__((unused)), + u32 num __attribute__((unused))); + +void +port_null_add_lua_multret(void *data __attribute__((unused)), + struct lua_State *L __attribute__((unused))); /** These do not have state currently, thus a single * instance is sufficient. */ -Port *port_null; -Port *port_iproto; - -/** Init the subsystem. */ -void port_init(); -/** Stop the susbystem. */ -void port_free(); +extern struct port port_null; +extern struct port port_iproto; #endif /* INCLUDES_TARANTOOL_BOX_PORT_H */ diff --git a/mod/box/port.m b/mod/box/port.m index bfd200cbad80db5a53230e827737af7fbf430c75..ee0b67d33506ded550df5c040686e9c93476426e 100644 --- a/mod/box/port.m +++ b/mod/box/port.m @@ -60,56 +60,58 @@ tuple_unref(void *tuple) } void -fiber_ref_tuple(struct tuple *tuple) +iov_ref_tuple(struct tuple *tuple) { tuple_ref(tuple, 1); fiber_register_cleanup(tuple_unref, tuple); } -@implementation Port -- (void) addU32: (u32 *) p_u32 +u32* +port_null_add_u32(void *data __attribute__((unused))) { - [self subclassResponsibility: _cmd]; - (void) p_u32; + static u32 dummy; + return &dummy; } -- (void) dupU32: (u32) u32 + +void +port_null_dup_u32(void *data __attribute__((unused)), + u32 num __attribute__((unused))) { - [self subclassResponsibility: _cmd]; - (void) u32; } -- (void) addTuple: (struct tuple *) tuple + +static void +port_null_add_tuple(void *data __attribute__((unused)), + struct tuple *tuple __attribute__((unused))) { - [self subclassResponsibility: _cmd]; - (void) tuple; } -- (void) addLuaMultret: (struct lua_State *) L + +void +port_null_add_lua_multret(void *data __attribute__((unused)), + struct lua_State *L __attribute__((unused))) { - [self subclassResponsibility: _cmd]; - (void) L; } -@end - -@interface PortIproto: Port -@end -@implementation PortIproto - -- (void) addU32: (u32 *) p_u32 +static u32* +port_iproto_add_u32(void *data __attribute__((unused))) { + u32 *p_u32 = palloc(fiber->gc_pool, sizeof(u32)); iov_add(p_u32, sizeof(u32)); + return p_u32; } -- (void) dupU32: (u32) u32 +static void +port_iproto_dup_u32(void *data __attribute__((unused)), u32 u32) { iov_dup(&u32, sizeof(u32)); } -- (void) addTuple: (struct tuple *) tuple +static void +port_iproto_add_tuple(void *data __attribute__((unused)), struct tuple *tuple) { size_t len = tuple_len(tuple); if (len > BOX_REF_THRESHOLD) { - fiber_ref_tuple(tuple); + iov_ref_tuple(tuple); iov_add(&tuple->bsize, len); } else { iov_dup(&tuple->bsize, len); @@ -184,7 +186,8 @@ iov_add_lua_table(struct lua_State *L, int index) } } -void iov_add_ret(struct lua_State *L, int index) +static void +iov_add_ret(struct lua_State *L, int index) { int type = lua_type(L, index); struct tuple *tuple; @@ -244,7 +247,7 @@ void iov_add_ret(struct lua_State *L, int index) tnt_raise(ClientError, :ER_PROC_RET, lua_typename(L, type)); break; } - fiber_ref_tuple(tuple); + iov_ref_tuple(tuple); iov_add(&tuple->bsize, tuple_len(tuple)); } @@ -256,38 +259,36 @@ void iov_add_ret(struct lua_State *L, int index) * and return the number of return values first, and * then each return value as a tuple. */ -- (void) addLuaMultret: (struct lua_State *) L +static void +port_iproto_add_lua_multret(void *data __attribute__((unused)), struct lua_State *L) { int nargs = lua_gettop(L); iov_dup(&nargs, sizeof(u32)); for (int i = 1; i <= nargs; ++i) iov_add_ret(L, i); } -@end +struct port_vtab port_null_vtab = { + port_null_add_u32, + port_null_dup_u32, + port_null_add_tuple, + port_null_add_lua_multret, +}; -@implementation PortNull -- (void) addU32: (u32 *) p_u32 { (void) p_u32; } -- (void) dupU32: (u32) u32 { (void) u32; } -- (void) addTuple: (struct tuple *) tuple { (void) tuple; } -- (void) addLuaMultret: (struct lua_State *) L { (void) L; } -@end +struct port_vtab port_iproto_vtab = { + port_iproto_add_u32, + port_iproto_dup_u32, + port_iproto_add_tuple, + port_iproto_add_lua_multret, +}; -Port *port_null; -Port *port_iproto; +struct port port_null = { + .vtab = &port_null_vtab, + .data = NULL, +}; -void -port_init() -{ - port_iproto = [[PortIproto alloc] init]; - port_null = [[PortNull alloc] init]; -} +struct port port_iproto = { + .vtab = &port_iproto_vtab, + .data = NULL, +}; -void -port_free() -{ - if (port_iproto) - [port_iproto free]; - if (port_null) - [port_null free]; -} diff --git a/mod/box/request.h b/mod/box/request.h index e055aa8ec1efb5bc59b2fce7a3dfc4a730d69555..815b3b80da48e6d0ef781d0f830bb577f2647ac1 100644 --- a/mod/box/request.h +++ b/mod/box/request.h @@ -38,8 +38,8 @@ enum { /** A limit on how many operations a single UPDATE can have. */ BOX_UPDATE_OP_CNT_MAX = 4000, }; -@class Port; struct txn; +struct port; #define BOX_RETURN_TUPLE 0x01 #define BOX_ADD 0x02 @@ -107,7 +107,7 @@ request_is_select(u32 type) + (Request *) alloc; + (Request *) build: (u32) type_arg; - (id) init: (struct tbuf *) data_arg; -- (void) execute: (struct txn *) txn :(Port *) port; +- (void) execute: (struct txn *) txn :(struct port *) port; @end #endif /* TARANTOOL_BOX_REQUEST_H_INCLUDED */ diff --git a/mod/box/request.m b/mod/box/request.m index 1d11701090c40686d9975c484252c1dbf126113f..80655d6d9a4c2c7c0fb581d2b71fb167851d9674 100644 --- a/mod/box/request.m +++ b/mod/box/request.m @@ -66,23 +66,23 @@ read_space(struct tbuf *data) } static void -port_send_tuple(u32 flags, Port *port, struct tuple *tuple) +port_send_tuple(u32 flags, struct port *port, struct tuple *tuple) { if (tuple) { - [port dupU32: 1]; /* affected tuples */ + port_dup_u32(port, 1); /* affected tuples */ if (flags & BOX_RETURN_TUPLE) - [port addTuple: tuple]; + port_add_tuple(port, tuple); } else { - [port dupU32: 0]; /* affected tuples. */ + port_dup_u32(port, 0); /* affected tuples. */ } } @interface Replace: Request -- (void) execute: (struct txn *) txn :(Port *) port; +- (void) execute: (struct txn *) txn :(struct port *) port; @end @implementation Replace -- (void) execute: (struct txn *) txn :(Port *) port +- (void) execute: (struct txn *) txn :(struct port *) port { txn_add_redo(txn, type, data); struct space *sp = read_space(data); @@ -112,10 +112,10 @@ port_send_tuple(u32 flags, Port *port, struct tuple *tuple) txn_add_undo(txn, sp, old_tuple, txn->new_tuple); - [port dupU32: 1]; /* Affected tuples */ + port_dup_u32(port, 1); /* Affected tuples */ if (flags & BOX_RETURN_TUPLE) - [port addTuple: txn->new_tuple]; + port_add_tuple(port, txn->new_tuple); } @end @@ -182,7 +182,7 @@ port_send_tuple(u32 flags, Port *port, struct tuple *tuple) */ @interface Update: Request -- (void) execute: (struct txn *) txn :(Port *) port; +- (void) execute: (struct txn *) txn :(struct port *) port; @end /** Argument of SET operation. */ @@ -709,7 +709,7 @@ update_read_ops(struct tbuf *data, u32 op_cnt) @implementation Update -- (void) execute: (struct txn *) txn :(Port *) port +- (void) execute: (struct txn *) txn :(struct port *) port { txn_add_redo(txn, type, data); struct space *sp = read_space(data); @@ -747,11 +747,11 @@ update_read_ops(struct tbuf *data, u32 op_cnt) /** }}} */ @interface Select: Request -- (void) execute: (struct txn *) txn :(Port *) port; +- (void) execute: (struct txn *) txn :(struct port *) port; @end @implementation Select -- (void) execute: (struct txn *) txn :(Port *) port +- (void) execute: (struct txn *) txn :(struct port *) port { (void) txn; /* Not used. */ struct space *sp = read_space(data); @@ -763,9 +763,8 @@ update_read_ops(struct tbuf *data, u32 op_cnt) if (count == 0) tnt_raise(IllegalParams, :"tuple count must be positive"); - uint32_t *found = palloc(fiber->gc_pool, sizeof(*found)); + uint32_t *found = port_add_u32(port); *found = 0; - [port addU32: found]; ERROR_INJECT_EXCEPTION(ERRINJ_TESTING); @@ -793,7 +792,7 @@ update_read_ops(struct tbuf *data, u32 op_cnt) continue; } - [port addTuple: tuple]; + port_add_tuple(port, tuple); if (limit == ++(*found)) break; @@ -805,11 +804,11 @@ update_read_ops(struct tbuf *data, u32 op_cnt) @end @interface Delete: Request -- (void) execute: (struct txn *) txn :(Port *) port; +- (void) execute: (struct txn *) txn :(struct port *) port; @end @implementation Delete -- (void) execute: (struct txn *) txn :(Port *) port +- (void) execute: (struct txn *) txn :(struct port *) port { txn_add_redo(txn, type, data); u32 flags = 0; @@ -875,7 +874,7 @@ update_read_ops(struct tbuf *data, u32 op_cnt) return self; } -- (void) execute: (struct txn *) txn :(Port *) port +- (void) execute: (struct txn *) txn :(struct port *) port { (void) txn; (void) port;