improved thread/exception-safety for window creation and show function - gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
path: root/agg-plot
diff options
context:
space:
mode:
authorfrancesco-ST <francesco.abbate@st.com>2011年01月03日 14:30:43 +0100
committerfrancesco <francesco.bbt@gmail.com>2011年01月03日 20:56:08 +0100
commit1d0382f13c23443d26a330fcb89742a7befe0450 (patch)
tree6733bb5bb062875205cde819ff14d291923e694a /agg-plot
parent7f73acc24c47f7e0ef6f367db12a184a23e5faa2 (diff)
downloadgsl-shell-1d0382f13c23443d26a330fcb89742a7befe0450.tar.gz
improved thread/exception-safety for window creation and show function
Signed-off-by: francesco-ST <francesco.abbate@st.com>
Diffstat (limited to 'agg-plot')
-rw-r--r--agg-plot/canvas-window-cpp.h 20
-rw-r--r--agg-plot/canvas-window.cpp 48
-rw-r--r--agg-plot/window-cpp.h 4
-rw-r--r--agg-plot/window.cpp 35
4 files changed, 68 insertions, 39 deletions
diff --git a/agg-plot/canvas-window-cpp.h b/agg-plot/canvas-window-cpp.h
index 65c1453a..9a02603a 100644
--- a/agg-plot/canvas-window-cpp.h
+++ b/agg-plot/canvas-window-cpp.h
@@ -1,10 +1,17 @@
#ifndef CANVAS_WINDOW_CPP_H
#define CANVAS_WINDOW_CPP_H
+#include <memory>
+
#include "platform_support_ext.h"
#include "agg_trans_affine.h"
#include "agg_color_rgba.h"
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+}
+
#include "defs.h"
#include "drawable.h"
#include "canvas.h"
@@ -19,14 +26,21 @@ protected:
public:
+ struct thread_info {
+ lua_State *L;
+ canvas_window *win;
+ int window_id;
+
+ thread_info (lua_State *L, canvas_window *win) : L(L), win(win) {};
+ };
+
enum win_status_e { not_ready, starting, running, error, closed };
- int id;
enum win_status_e status;
canvas_window(agg::rgba& bgcol) :
platform_support_ext(agg::pix_format_bgr24, true),
- m_canvas(NULL), m_bgcolor(bgcol), m_matrix(), id(-1), status(not_ready)
+ m_canvas(NULL), m_bgcolor(bgcol), m_matrix(), status(not_ready)
{ };
virtual ~canvas_window()
@@ -38,7 +52,7 @@ public:
virtual void on_init();
virtual void on_resize(int sx, int sy);
- void start_new_thread (lua_State *L);
+ bool start_new_thread (std::auto_ptr<thread_info>& inf);
void scale (agg::trans_affine& m) { trans_affine_compose (m, m_matrix); };
};
diff --git a/agg-plot/canvas-window.cpp b/agg-plot/canvas-window.cpp
index 911d504b..f5a1bdaf 100644
--- a/agg-plot/canvas-window.cpp
+++ b/agg-plot/canvas-window.cpp
@@ -18,13 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include <memory>
-
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-}
-
#include "defs.h"
#include "canvas-window-cpp.h"
#include "resource-manager.h"
@@ -45,13 +38,6 @@ static void * canvas_thread_function (void *_win);
__END_DECLS
-struct canvas_thread_info {
- lua_State *L;
- canvas_window *win;
-
- canvas_thread_info (lua_State *L, canvas_window *win) : L(L), win(win) {};
-};
-
void
canvas_window::on_resize(int sx, int sy)
{
@@ -70,13 +56,10 @@ canvas_window::on_init()
this->on_resize(width(), height());
}
-void
-canvas_window::start_new_thread (lua_State *L)
+bool canvas_window::start_new_thread (std::auto_ptr<canvas_window::thread_info>& inf)
{
if (status != not_ready && status != closed)
- return;
-
- this->id = object_index_add (L, -1);
+ return false;
pthread_attr_t attr[1];
pthread_t win_thread[1];
@@ -84,29 +67,30 @@ canvas_window::start_new_thread (lua_State *L)
pthread_attr_init (attr);
pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED);
- this->lock();
-
this->status = canvas_window::starting;
- canvas_thread_info *inf = new canvas_thread_info(L, this);
- if (pthread_create(win_thread, attr, canvas_thread_function, (void*) inf))
+ void *user_data = (void *) inf.get();
+ if (pthread_create(win_thread, attr, canvas_thread_function, user_data))
{
- delete inf;
- object_index_remove (L, this->id);
- pthread_attr_destroy (attr);
-
this->status = canvas_window::error;
-
- luaL_error(L, "error creating thread");
+ pthread_attr_destroy (attr);
+ return false;
+ }
+ else
+ {
+ inf.release();
+ pthread_attr_destroy (attr);
}
- pthread_attr_destroy (attr);
+ return true;
}
void *
canvas_thread_function (void *_inf)
{
- std::auto_ptr<canvas_thread_info> inf((canvas_thread_info *) _inf);
+ typedef canvas_window::thread_info thread_info;
+
+ std::auto_ptr<thread_info> inf((thread_info *) _inf);
platform_support_ext::prepare();
canvas_window *win = inf->win;
@@ -125,7 +109,7 @@ canvas_thread_function (void *_inf)
win->unlock();
GSL_SHELL_LOCK();
- object_index_remove (inf->L, win->id);
+ object_index_remove (inf->L, inf->window_id);
GSL_SHELL_UNLOCK();
return NULL;
diff --git a/agg-plot/window-cpp.h b/agg-plot/window-cpp.h
index 0bb13e91..6c149d83 100644
--- a/agg-plot/window-cpp.h
+++ b/agg-plot/window-cpp.h
@@ -22,9 +22,10 @@ public:
invalid_split_string,
invalid_slot,
};
-
typedef plot<drawable, lua_management> plot_type;
+ int window_id;
+
typedef agg::trans_affine bmatrix;
struct ref {
@@ -76,6 +77,7 @@ public:
int attach(lua_plot *plot, const char *spec);
void draw_slot(int slot_id, bool update_req);
void refresh_slot(int slot_id);
+ bool start(lua_State *L);
void save_slot_image(int slot_id);
void restore_slot_image(int slot_id);
diff --git a/agg-plot/window.cpp b/agg-plot/window.cpp
index 0fbcf000..32ff234d 100644
--- a/agg-plot/window.cpp
+++ b/agg-plot/window.cpp
@@ -418,18 +418,46 @@ int window_generic_oper_ext (lua_State *L,
return 0;
}
+bool window::start (lua_State *L)
+{
+ this->lock();
+
+ if (this->status != canvas_window::running)
+ {
+ typedef canvas_window::thread_info thread_info;
+ std::auto_ptr<thread_info> inf(new thread_info(L, this));
+
+ this->window_id = object_index_add (L, -1);
+ inf->window_id = this->window_id;
+
+ if (! this->start_new_thread (inf))
+ {
+ object_index_remove (L, this->window_id);
+ this->unlock();
+ return false;
+ }
+ }
+ else
+ {
+ this->unlock();
+ return false;
+ }
+
+ return true;
+}
+
int
window_new (lua_State *L)
{
window *win = push_new_object<window>(L, GS_WINDOW, colors::white);
const char *spec = lua_tostring (L, 1);
- win->start_new_thread (L);
+ if (! win->start(L))
+ return luaL_error (L, "error during window initialization");
if (spec)
{
win->split(spec);
- // return luaL_error(L, window::error_message(window::invalid_split_string));
}
return 1;
@@ -439,7 +467,8 @@ int
window_show (lua_State *L)
{
window *win = object_check<window>(L, 1, GS_WINDOW);
- win->start_new_thread (L);
+ if (! win->start(L))
+ return luaL_error (L, "error during window initialization");
return 0;
}
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月17日 06:05:48 +0000

AltStyle によって変換されたページ (->オリジナル) /