refactor(util/script_state): remove unsafe unguarded_apply

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-11-27 15:14:26 -08:00
parent 75b4a96d0e
commit b038636ff5
2 changed files with 34 additions and 48 deletions

View file

@ -301,9 +301,8 @@ class data_channel {
std::condition_variable m_cv; std::condition_variable m_cv;
public: public:
data_channel() { data_channel() {
m_channel.unguarded_apply([&](lua_State * channel) { lua_State * channel = m_channel.m_ptr->m_state;
m_ini = lua_gettop(channel); m_ini = lua_gettop(channel);
});
} }
/** /**
@ -316,12 +315,11 @@ public:
if (last < first) if (last < first)
return; return;
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
m_channel.unguarded_apply([&](lua_State * channel) { lua_State * channel = m_channel.m_ptr->m_state;
bool was_empty = lua_gettop(channel) == m_ini; bool was_empty = lua_gettop(channel) == m_ini;
copy_values(src, first, last, channel); copy_values(src, first, last, channel);
if (was_empty) if (was_empty)
m_cv.notify_one(); m_cv.notify_one();
});
} }
/** /**
@ -330,33 +328,32 @@ public:
*/ */
int read(lua_State * tgt, int i) { int read(lua_State * tgt, int i) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
return m_channel.unguarded_apply([&](lua_State * channel) { lua_State * channel = m_channel.m_ptr->m_state;
if (i > 0) { if (i > 0) {
// i is the position of the timeout argument // i is the position of the timeout argument
std::chrono::milliseconds dura(luaL_checkinteger(tgt, i)); std::chrono::milliseconds dura(luaL_checkinteger(tgt, i));
if (lua_gettop(channel) == m_ini) if (lua_gettop(channel) == m_ini)
m_cv.wait_for(lock, dura); m_cv.wait_for(lock, dura);
if (lua_gettop(channel) == m_ini) { if (lua_gettop(channel) == m_ini) {
// timeout... // timeout...
lua_pushboolean(tgt, false); lua_pushboolean(tgt, false);
lua_pushnil(tgt); lua_pushnil(tgt);
return 2; return 2;
} else { } else {
lua_pushboolean(tgt, true); lua_pushboolean(tgt, true);
copy_values(channel, m_ini + 1, m_ini + 1, tgt); copy_values(channel, m_ini + 1, m_ini + 1, tgt);
lua_remove(channel, m_ini + 1); lua_remove(channel, m_ini + 1);
return 2; return 2;
} }
} else { } else {
while (lua_gettop(channel) == m_ini) { while (lua_gettop(channel) == m_ini) {
check_interrupted(); check_interrupted();
m_cv.wait_for(lock, g_small_delay); m_cv.wait_for(lock, g_small_delay);
} }
copy_values(channel, m_ini + 1, m_ini + 1, tgt); copy_values(channel, m_ini + 1, m_ini + 1, tgt);
lua_remove(channel, m_ini + 1); lua_remove(channel, m_ini + 1);
return 1; return 1;
} }
});
} }
}; };

View file

@ -22,6 +22,7 @@ private:
friend script_state to_script_state(lua_State * L); friend script_state to_script_state(lua_State * L);
std::recursive_mutex & get_mutex(); std::recursive_mutex & get_mutex();
lua_State * get_state(); lua_State * get_state();
friend class data_channel;
public: public:
script_state(); script_state();
virtual ~script_state(); virtual ~script_state();
@ -46,18 +47,6 @@ public:
return f(get_state()); return f(get_state());
} }
/**
\brief Similar to \c apply, but a lock is not used to guarantee
exclusive access to the lua_State object.
\warning It is the caller resposability to guarantee that the object is not being
concurrently accessed.
*/
template<typename F>
typename std::result_of<F(lua_State * L)>::type unguarded_apply(F && f) {
return f(get_state());
}
typedef void (*reg_fn)(lua_State *); // NOLINT typedef void (*reg_fn)(lua_State *); // NOLINT
static void register_module(reg_fn f); static void register_module(reg_fn f);