123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #define LUA_LIB
- #include "skynet.h"
- #include <lua.h>
- #include <lauxlib.h>
- #include <stdint.h>
- #include <string.h>
- #include "atomic.h"
- struct mc_package {
- ATOM_INT reference;
- uint32_t size;
- void *data;
- };
- static int
- pack(lua_State *L, void *data, size_t size) {
- struct mc_package * pack = skynet_malloc(sizeof(struct mc_package));
- ATOM_INIT(&pack->reference, 0);
- pack->size = (uint32_t)size;
- pack->data = data;
- struct mc_package ** ret = skynet_malloc(sizeof(*ret));
- *ret = pack;
- lua_pushlightuserdata(L, ret);
- lua_pushinteger(L, sizeof(ret));
- return 2;
- }
- /*
- lightuserdata
- integer size
- return lightuserdata, sizeof(struct mc_package *)
- */
- static int
- mc_packlocal(lua_State *L) {
- void * data = lua_touserdata(L, 1);
- size_t size = (size_t)luaL_checkinteger(L, 2);
- if (size != (uint32_t)size) {
- return luaL_error(L, "Size should be 32bit integer");
- }
- return pack(L, data, size);
- }
- /*
- lightuserdata
- integer size
- return lightuserdata, sizeof(struct mc_package *)
- */
- static int
- mc_packremote(lua_State *L) {
- void * data = lua_touserdata(L, 1);
- size_t size = (size_t)luaL_checkinteger(L, 2);
- if (size != (uint32_t)size) {
- return luaL_error(L, "Size should be 32bit integer");
- }
- void * msg = skynet_malloc(size);
- memcpy(msg, data, size);
- return pack(L, msg, size);
- }
- /*
- lightuserdata struct mc_package **
- integer size (must be sizeof(struct mc_package *)
- return package, lightuserdata, size
- */
- static int
- mc_unpacklocal(lua_State *L) {
- struct mc_package ** pack = lua_touserdata(L,1);
- int sz = luaL_checkinteger(L,2);
- if (sz != sizeof(pack)) {
- return luaL_error(L, "Invalid multicast package size %d", sz);
- }
- lua_pushlightuserdata(L, *pack);
- lua_pushlightuserdata(L, (*pack)->data);
- lua_pushinteger(L, (lua_Integer)((*pack)->size));
- return 3;
- }
- /*
- lightuserdata struct mc_package **
- integer reference
- return mc_package *
- */
- static int
- mc_bindrefer(lua_State *L) {
- struct mc_package ** pack = lua_touserdata(L,1);
- int ref = luaL_checkinteger(L,2);
- if (ATOM_LOAD(&(*pack)->reference) != 0) {
- return luaL_error(L, "Can't bind a multicast package more than once");
- }
- ATOM_STORE(&(*pack)->reference , ref);
- lua_pushlightuserdata(L, *pack);
- skynet_free(pack);
- return 1;
- }
- /*
- lightuserdata struct mc_package *
- */
- static int
- mc_closelocal(lua_State *L) {
- struct mc_package *pack = lua_touserdata(L,1);
- int ref = ATOM_FDEC(&pack->reference)-1;
- if (ref <= 0) {
- skynet_free(pack->data);
- skynet_free(pack);
- if (ref < 0) {
- return luaL_error(L, "Invalid multicast package reference %d", ref);
- }
- }
- return 0;
- }
- /*
- lightuserdata struct mc_package **
- return lightuserdata/size
- */
- static int
- mc_remote(lua_State *L) {
- struct mc_package **ptr = lua_touserdata(L,1);
- struct mc_package *pack = *ptr;
- lua_pushlightuserdata(L, pack->data);
- lua_pushinteger(L, (lua_Integer)(pack->size));
- skynet_free(pack);
- skynet_free(ptr);
- return 2;
- }
- static int
- mc_nextid(lua_State *L) {
- uint32_t id = (uint32_t)luaL_checkinteger(L, 1);
- id += 256;
- // remove the highest bit, see #1139
- lua_pushinteger(L, id & 0x7fffffffu);
- return 1;
- }
- LUAMOD_API int
- luaopen_skynet_multicast_core(lua_State *L) {
- luaL_Reg l[] = {
- { "pack", mc_packlocal },
- { "unpack", mc_unpacklocal },
- { "bind", mc_bindrefer },
- { "close", mc_closelocal },
- { "remote", mc_remote },
- { "packremote", mc_packremote },
- { "nextid", mc_nextid },
- { NULL, NULL },
- };
- luaL_checkversion(L);
- luaL_newlib(L,l);
- return 1;
- }
|