diff options
author | Rob Kendrick (trite) <rjek@rjek.com> | 2013-08-27 11:32:16 +0100 |
---|---|---|
committer | Rob Kendrick (trite) <rjek@rjek.com> | 2013-08-27 11:32:16 +0100 |
commit | 47c4323a22541dad7d2a4052dd6a80959d941db1 (patch) | |
tree | 622ef0e2c11146e723a7a24630f3a69154ef9daa | |
parent | 6fdfdb83d119617d67409c6c10fe5119a735db8e (diff) | |
download | luxio-47c4323a22541dad7d2a4052dd6a80959d941db1.tar.gz |
Change message queues to use user data. Include simple test scripts.
-rw-r--r-- | luxio.c | 87 | ||||
-rw-r--r-- | tests/test-mqueue-read.lua | 29 | ||||
-rw-r--r-- | tests/test-mqueue-write.lua | 15 |
3 files changed, 108 insertions, 23 deletions
@@ -1797,14 +1797,31 @@ luxio_nanosleep(lua_State *L) /* 14.2.5 */ /**# Message passing *********************************************************/ -#if defined(_POSIX_MESSAGE_PASSING) && defined(__linux__) - -/* TODO: This code assumes mqd_t is an integer. On BSD it is not, so - * this needs to be rewritten using userdata. - */ +#if defined(_POSIX_MESSAGE_PASSING) #include <mqueue.h> +#define LUXIO_MQ_METATABLE_NAME "luxio.mq" + +struct luxio_mq_data { + mqd_t mq; + char name[NAME_MAX]; +}; + +static int +luxio__mq_tostring(lua_State *L) +{ + char buf[NAME_MAX + 64]; + + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); + + sprintf(buf, "<mq %p %s>", (void *)(intptr_t)m->mq, m->name); + + lua_pushstring(L, buf); + return 1; +} + /**% mq_open * retval = mq_open(name, oflag[, mode, attr]); * retval, errno = mq_open(name, oflag[, mode]) @@ -1816,6 +1833,7 @@ luxio_mq_open(lua_State *L) /* 15.2.1 */ int oflag = luaL_checkinteger(L, 2); mode_t mode = luaL_optinteger(L, 3, INVALID_MODE); mqd_t mq; + struct luxio_mq_data *m; if ((oflag & O_CREAT) && mode == INVALID_MODE) { lua_pushstring(L, "mq_open with O_CREATE called with no mode"); @@ -1828,7 +1846,23 @@ luxio_mq_open(lua_State *L) /* 15.2.1 */ mq = mq_open(name, oflag); } - lua_pushinteger(L, mq); + if (mq == (mqd_t)-1) { + lua_pushnumber(L, -1); + lua_pushinteger(L, errno); + + return 2; + } + + m = lua_newuserdata(L, sizeof(*m)); + m->mq = mq; + strncpy(m->name, name, NAME_MAX); + + if (luaL_newmetatable(L, LUXIO_MQ_METATABLE_NAME) != 0) { + lua_pushcfunction(L, luxio__mq_tostring); + lua_setfield(L, -2, "__tostring"); + } + + lua_setmetatable(L, -2); lua_pushinteger(L, errno); return 2; @@ -1841,9 +1875,10 @@ luxio_mq_open(lua_State *L) /* 15.2.1 */ static int luxio_mq_close(lua_State *L) /* 15.2.2 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); - lua_pushinteger(L, mq_close(mq)); + lua_pushinteger(L, mq_close(m->mq)); lua_pushinteger(L, errno); return 2; } @@ -1869,12 +1904,13 @@ luxio_mq_unlink(lua_State *L) /* 15.2.3 */ static int luxio_mq_send(lua_State *L) /* 15.2.4 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); size_t msg_len; const char *msg_ptr = luaL_checklstring(L, 2, &msg_len); unsigned int msg_prio = luaL_checkinteger(L, 3); - lua_pushinteger(L, mq_send(mq, msg_ptr, msg_len, msg_prio)); + lua_pushinteger(L, mq_send(m->mq, msg_ptr, msg_len, msg_prio)); lua_pushinteger(L, errno); return 2; } @@ -1886,18 +1922,19 @@ luxio_mq_send(lua_State *L) /* 15.2.4 */ static int luxio_mq_receive(lua_State *L) /* 15.2.5 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); unsigned int msg_prio; struct mq_attr attr; /* Find out the maximum size of a message */ - if (mq_getattr(mq, &attr) == -1) { + if (mq_getattr(m->mq, &attr) == -1) { lua_pushinteger(L, -1); lua_pushinteger(L, errno); return 2; } else { char msg_ptr[attr.mq_msgsize]; - int r = mq_receive(mq, msg_ptr, sizeof(msg_ptr), &msg_prio); + int r = mq_receive(m->mq, msg_ptr, sizeof(msg_ptr), &msg_prio); lua_pushinteger(L, r); lua_pushinteger(L, errno); if (r == -1) { @@ -1939,11 +1976,12 @@ luxio_make_attr_table(lua_State *L, struct mq_attr *attr) static int luxio_mq_setattr(lua_State *L) /* 15.2.7 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); struct mq_attr mqstat = { luaL_checkinteger(L, 2), 0, 0, 0 }; struct mq_attr omqstat = { 0, 0, 0, 0 }; - lua_pushinteger(L, mq_setattr(mq, &mqstat, &omqstat)); + lua_pushinteger(L, mq_setattr(m->mq, &mqstat, &omqstat)); lua_pushinteger(L, errno); luxio_make_attr_table(L, &omqstat); @@ -1957,10 +1995,11 @@ luxio_mq_setattr(lua_State *L) /* 15.2.7 */ static int luxio_mq_getattr(lua_State *L) /* 15.2.8 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); struct mq_attr mqstat; - lua_pushinteger(L, mq_getattr(mq, &mqstat)); + lua_pushinteger(L, mq_getattr(m->mq, &mqstat)); lua_pushinteger(L, errno); luxio_make_attr_table(L, &mqstat); @@ -1976,7 +2015,8 @@ luxio_mq_getattr(lua_State *L) /* 15.2.8 */ static int luxio_mq_timedsend(lua_State *L) /* POSIX.1-2001 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); size_t msg_len; const char *msg_ptr = luaL_checklstring(L, 2, &msg_len); unsigned int msg_prio = luaL_checkinteger(L, 3); @@ -1984,7 +2024,7 @@ luxio_mq_timedsend(lua_State *L) /* POSIX.1-2001 */ long tv_nsec = luaL_checkinteger(L, 5); struct timespec abs_timeout = { tv_secs, tv_nsec }; - lua_pushinteger(L, mq_timedsend(mq, msg_ptr, msg_len, msg_prio, + lua_pushinteger(L, mq_timedsend(m->mq, msg_ptr, msg_len, msg_prio, &abs_timeout)); lua_pushinteger(L, errno); return 2; @@ -1997,7 +2037,8 @@ luxio_mq_timedsend(lua_State *L) /* POSIX.1-2001 */ static int luxio_mq_timedreceive(lua_State *L) /* POSIX.1-2001 */ { - mqd_t mq = luaL_checkinteger(L, 1); + struct luxio_mq_data *m = + luaL_checkudata(L, 1, LUXIO_MQ_METATABLE_NAME); unsigned int msg_prio; struct mq_attr attr; time_t tv_secs = luaL_checkinteger(L, 2); @@ -2005,14 +2046,14 @@ luxio_mq_timedreceive(lua_State *L) /* POSIX.1-2001 */ struct timespec abs_timeout = { tv_secs, tv_nsec }; /* Find out the maximum size of a message */ - if (mq_getattr(mq, &attr) == -1) { + if (mq_getattr(m->mq, &attr) == -1) { lua_pushinteger(L, -1); lua_pushinteger(L, errno); return 2; } else { char msg_ptr[attr.mq_msgsize]; - int r = mq_timedreceive(mq, msg_ptr, sizeof(msg_ptr), &msg_prio, - &abs_timeout); + int r = mq_timedreceive(m->mq, msg_ptr, sizeof(msg_ptr), + &msg_prio, &abs_timeout); lua_pushinteger(L, r); lua_pushinteger(L, errno); if (r == -1) { diff --git a/tests/test-mqueue-read.lua b/tests/test-mqueue-read.lua new file mode 100644 index 0000000..d8aeb90 --- /dev/null +++ b/tests/test-mqueue-read.lua @@ -0,0 +1,29 @@ +l = require "luxio" +s = require "luxio.simple" + +local mq, errno + +mq, errno = l.mq_open("/luxio.test", l.bit.bor(l.O_RDONLY, l.O_CREAT), s.tomode "0777") + +if mq == -1 then + error(l.strerror(errno)) +end + + +io.stdout:write(tostring(mq) .. " attributes:\n") + +r, errno, attr = l.mq_getattr(mq) + +for i, v in pairs(attr) do + io.stdout:write(" ", i, " ", v, "\n") +end + +local message, bytes, priority + +repeat + bytes, errno, message, priority = l.mq_receive(mq) + print(bytes, errno, message, priority) +until message == "QUIT" or bytes == -1 + +l.mq_close(mq) +l.mq_unlink "/luxio-test" diff --git a/tests/test-mqueue-write.lua b/tests/test-mqueue-write.lua new file mode 100644 index 0000000..42eff87 --- /dev/null +++ b/tests/test-mqueue-write.lua @@ -0,0 +1,15 @@ +l = require "luxio" +s = require "luxio.simple" + +local mq, errno + +mq, errno = l.mq_open("/luxio.test", l.O_WRONLY) + +if mq == -1 then + error(l.strerror(errno)) +end + +r, errno = l.mq_send(mq, table.concat({ ... }, " "), 42) + +print(r) + |