Mercurial > love-experiments
diff src/modules/thread/wrap_Channel.cpp @ 1304:ee1448bb9680 minor
Fix race conditions and deadlocks in Channels (hopefully) (issue #554)
Also, this is a giant commit because of the official Code Style (tm) was applied.
| author | Bart van Strien <bart.bes+projects@gmail.com> |
|---|---|
| date | Wed, 30 Jan 2013 17:15:12 +0100 |
| parents | 1a59c21cd2f3 |
| children | f6ff61fc266f |
line wrap: on
line diff
--- a/src/modules/thread/wrap_Channel.cpp Sun Jan 27 20:04:16 2013 +0100 +++ b/src/modules/thread/wrap_Channel.cpp Wed Jan 30 17:15:12 2013 +0100 @@ -24,94 +24,108 @@ { namespace thread { - Channel *luax_checkchannel(lua_State *L, int idx) - { - return luax_checktype<Channel>(L, idx, "Channel", THREAD_CHANNEL_T); - } +void retainVariant(Channel *c, Variant *v) +{ + c->lockMutex(); + v->retain(); + c->unlockMutex(); +} + +void releaseVariant(Channel *c, Variant *v) +{ + c->lockMutex(); + v->release(); + c->unlockMutex(); +} + +Channel *luax_checkchannel(lua_State *L, int idx) +{ + return luax_checktype<Channel>(L, idx, "Channel", THREAD_CHANNEL_T); +} - int w_Channel_push(lua_State *L) - { - Channel *c = luax_checkchannel(L, 1); - Variant *var = Variant::fromLua(L, 2); - c->push(var); - var->release(); - return 0; - } +int w_Channel_push(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + Variant *var = Variant::fromLua(L, 2); + c->push(var); + releaseVariant(c, var); + return 0; +} - int w_Channel_supply(lua_State *L) +int w_Channel_supply(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + Variant *var = Variant::fromLua(L, 2); + c->supply(var); + releaseVariant(c, var); + return 0; +} + +int w_Channel_pop(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + Variant *var = c->pop(); + if (var) { - Channel *c = luax_checkchannel(L, 1); - Variant *var = Variant::fromLua(L, 2); - c->supply(var); - var->release(); - return 0; - } - - int w_Channel_pop(lua_State *L) - { - Channel *c = luax_checkchannel(L, 1); - Variant *var = c->pop(); - if (var) - { - var->toLua(L); - var->release(); - } - else - lua_pushnil(L); - return 1; - } - - int w_Channel_demand(lua_State *L) - { - Channel *c = luax_checkchannel(L, 1); - Variant *var = c->demand(); var->toLua(L); - var->release(); - return 1; + releaseVariant(c, var); } + else + lua_pushnil(L); + return 1; +} - int w_Channel_peek(lua_State *L) +int w_Channel_demand(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + Variant *var = c->demand(); + var->toLua(L); + releaseVariant(c, var); + return 1; +} + +int w_Channel_peek(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + Variant *var = c->peek(); + if (var) { - Channel *c = luax_checkchannel(L, 1); - Variant *var = c->peek(); - if (var) - { - var->toLua(L); - var->release(); - } - else - lua_pushnil(L); - return 1; + var->toLua(L); + releaseVariant(c, var); } - - int w_Channel_count(lua_State *L) - { - Channel *c = luax_checkchannel(L, 1); - lua_pushnumber(L, c->count()); - return 1; - } + else + lua_pushnil(L); + return 1; +} - int w_Channel_clear(lua_State *L) - { - Channel *c = luax_checkchannel(L, 1); - c->clear(); - return 0; - } +int w_Channel_count(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + lua_pushnumber(L, c->count()); + return 1; +} + +int w_Channel_clear(lua_State *L) +{ + Channel *c = luax_checkchannel(L, 1); + c->clear(); + return 0; +} - static const luaL_Reg type_functions[] = { - { "push", w_Channel_push }, - { "supply", w_Channel_supply }, - { "pop", w_Channel_pop }, - { "demand", w_Channel_demand }, - { "peek", w_Channel_peek }, - { "count", w_Channel_count }, - { "clear", w_Channel_clear }, - { 0, 0 } - }; +static const luaL_Reg type_functions[] = { + { "push", w_Channel_push }, + { "supply", w_Channel_supply }, + { "pop", w_Channel_pop }, + { "demand", w_Channel_demand }, + { "peek", w_Channel_peek }, + { "count", w_Channel_count }, + { "clear", w_Channel_clear }, + { 0, 0 } +}; - extern "C" int luaopen_channel(lua_State *L) - { - return luax_register_type(L, "Channel", type_functions); - } +extern "C" int luaopen_channel(lua_State *L) +{ + return luax_register_type(L, "Channel", type_functions); } } +}
