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

View file

@ -22,6 +22,7 @@ private:
friend script_state to_script_state(lua_State * L);
std::recursive_mutex & get_mutex();
lua_State * get_state();
friend class data_channel;
public:
script_state();
virtual ~script_state();
@ -46,18 +47,6 @@ public:
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
static void register_module(reg_fn f);