Changeset 4264


Ignore:
Timestamp:
2012-04-24 15:06:24 (2 years ago)
Author:
drobilla
Message:

Fix crashes when wrapper widget is destroyed by toolkit before suil cleanup
function is called.

Location:
trunk/suil
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/suil/NEWS

    r4201 r4264  
     1suil (9999) stable; 
     2 
     3  * Fix crashes when wrapper widget is destroyed by toolkit before 
     4    suil cleanup function is called. 
     5 
     6 -- David Robillard <d@drobilla.net> 
     7 
    18suil (0.6.0) stable; 
    29 
  • trunk/suil/src/gtk2_in_qt4.cpp

    r4160 r4264  
    7575    SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); 
    7676    wrapper->wrap = wrapper_wrap; 
    77     wrapper->free = (SuilWrapperFreeFunc)free; 
     77    wrapper->free = NULL; 
    7878    wrapper->impl = NULL; 
    7979 
  • trunk/suil/src/instance.c

    r4173 r4264  
    258258        free(instance->features); 
    259259 
    260         if (instance->wrapper) { 
    261             instance->wrapper->free(instance->wrapper); 
    262             dlclose(instance->wrapper->lib); 
    263         } 
    264260        if (instance->handle) { 
    265261            instance->descriptor->cleanup(instance->handle); 
     262        } 
     263        if (instance->wrapper) { 
     264            if (instance->wrapper->free) { 
     265                instance->wrapper->free(instance->wrapper); 
     266            } 
     267            dlclose(instance->wrapper->lib); 
     268            free(instance->wrapper); 
    266269        } 
    267270        dlclose(instance->lib_handle); 
  • trunk/suil/src/qt4_in_gtk2.cpp

    r4162 r4264  
    3535    QApplication*    app; 
    3636    QX11EmbedWidget* qembed; 
     37    SuilWrapper*     wrapper; 
    3738    SuilInstance*    instance; 
    3839}; 
     
    4748 
    4849static void 
    49 suil_qt_wrapper_dispose(GObject* gobject) 
     50suil_qt_wrapper_finalize(GObject* gobject) 
    5051{ 
    5152    SuilQtWrapper* const self = SUIL_QT_WRAPPER(gobject); 
    5253 
    53     if (self->qembed) { 
    54         delete self->qembed; 
    55         self->qembed = NULL; 
    56  
    57         delete self->app; 
    58         self->app = NULL; 
     54    if (self->instance->handle) { 
     55        self->instance->descriptor->cleanup(self->instance->handle); 
     56        self->instance->handle = NULL; 
    5957    } 
    6058 
    61     G_OBJECT_CLASS(suil_qt_wrapper_parent_class)->dispose(gobject); 
     59    delete self->qembed; 
     60    self->qembed = NULL; 
     61 
     62    delete self->app; 
     63    self->app = NULL; 
     64 
     65    self->wrapper->impl = NULL; 
     66 
     67    G_OBJECT_CLASS(suil_qt_wrapper_parent_class)->finalize(gobject); 
    6268} 
    6369 
     
    6773    GObjectClass* const gobject_class = G_OBJECT_CLASS(klass); 
    6874 
    69     gobject_class->dispose = suil_qt_wrapper_dispose; 
     75    gobject_class->finalize = suil_qt_wrapper_finalize; 
    7076} 
    7177 
     
    95101 
    96102    wrap->qembed   = new QX11EmbedWidget(); 
     103    wrap->wrapper  = wrapper; 
    97104    wrap->instance = instance; 
    98105 
     
    116123wrapper_free(SuilWrapper* wrapper) 
    117124{ 
    118     SuilQtWrapper* const wrap = SUIL_QT_WRAPPER( 
    119         g_object_new(SUIL_TYPE_QT_WRAPPER, NULL)); 
    120  
    121     gtk_object_destroy(GTK_OBJECT(wrap)); 
    122     free(wrap); 
     125    if (wrapper->impl) { 
     126        SuilQtWrapper* const wrap = SUIL_QT_WRAPPER(wrapper->impl); 
     127        gtk_object_destroy(GTK_OBJECT(wrap)); 
     128    } 
    123129} 
    124130 
     
    131137{ 
    132138    SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); 
    133     wrapper->wrap = wrapper_wrap; 
    134     wrapper->free = wrapper_free; 
    135     wrapper->impl = NULL; 
     139    wrapper->wrap    = wrapper_wrap; 
     140    wrapper->free    = wrapper_free; 
     141    wrapper->impl    = NULL; 
    136142 
    137143    SuilQtWrapper* const wrap = SUIL_QT_WRAPPER( 
     
    139145 
    140146    static int argc = 0; 
    141     wrap->app = new QApplication(argc, NULL, true); 
     147    wrap->app     = new QApplication(argc, NULL, true); 
     148    wrap->wrapper = NULL; 
    142149 
    143150    wrapper->impl = wrap; 
  • trunk/suil/src/x11_in_gtk2.c

    r4160 r4264  
    3030    GtkSocket     socket; 
    3131    GtkPlug*      plug; 
     32    SuilWrapper*  wrapper; 
    3233    SuilInstance* instance; 
    3334}; 
     
    4142G_DEFINE_TYPE(SuilX11Wrapper, suil_x11_wrapper, GTK_TYPE_SOCKET) 
    4243 
     44static gboolean 
     45on_plug_removed(GtkSocket* sock, gpointer data) 
     46{ 
     47    SuilX11Wrapper* const self = SUIL_X11_WRAPPER(sock); 
     48 
     49    if (self->instance->handle) { 
     50        self->instance->descriptor->cleanup(self->instance->handle); 
     51        self->instance->handle = NULL; 
     52    } 
     53 
     54    self->plug = NULL; 
     55    return TRUE; 
     56} 
     57 
    4358static void 
    44 wrap_widget_dispose(GObject* gobject) 
     59suil_x11_wrapper_finalize(GObject* gobject) 
    4560{ 
    46     G_OBJECT_CLASS(suil_x11_wrapper_parent_class)->dispose(gobject); 
     61    SuilX11Wrapper* const self = SUIL_X11_WRAPPER(gobject); 
     62 
     63    self->wrapper->impl = NULL; 
     64 
     65    G_OBJECT_CLASS(suil_x11_wrapper_parent_class)->finalize(gobject); 
    4766} 
    4867 
     
    5271    GObjectClass* const gobject_class = G_OBJECT_CLASS(klass); 
    5372 
    54     gobject_class->dispose = wrap_widget_dispose; 
     73    gobject_class->finalize = suil_x11_wrapper_finalize; 
    5574} 
    5675 
     
    86105 
    87106    instance->host_widget = GTK_WIDGET(wrap); 
     107    wrap->wrapper         = wrapper; 
    88108    wrap->instance        = instance; 
    89109 
     
    93113                           NULL); 
    94114 
     115    g_signal_connect(G_OBJECT(wrap), 
     116                     "plug-removed", 
     117                     G_CALLBACK(on_plug_removed), 
     118                     NULL); 
     119 
    95120    return 0; 
    96121} 
     
    99124wrapper_free(SuilWrapper* wrapper) 
    100125{ 
    101     free(wrapper); 
     126    if (wrapper->impl) { 
     127        SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(wrapper->impl); 
     128        gtk_object_destroy(GTK_OBJECT(wrap)); 
     129    } 
    102130} 
     131 
    103132 
    104133SUIL_API 
     
    111140{ 
    112141    SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); 
    113     wrapper->wrap        = wrapper_wrap; 
    114     wrapper->free        = wrapper_free; 
     142    wrapper->wrap = wrapper_wrap; 
     143    wrapper->free = wrapper_free; 
    115144 
    116145    SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER( 
    117146        g_object_new(SUIL_TYPE_X11_WRAPPER, NULL)); 
     147 
     148    wrap->wrapper = NULL; 
    118149 
    119150    wrapper->impl             = wrap; 
  • trunk/suil/src/x11_in_qt4.cpp

    r4160 r4264  
    5555    SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); 
    5656    wrapper->wrap = wrapper_wrap; 
    57     wrapper->free = (SuilWrapperFreeFunc)free; 
     57    wrapper->free = NULL; 
    5858 
    5959    QX11EmbedWidget* const ew = new QX11EmbedWidget(); 
  • trunk/suil/wscript

    r4202 r4264  
    88 
    99# Version of this package (even if built as a child) 
    10 SUIL_VERSION       = '0.6.0' 
     10SUIL_VERSION       = '0.6.1' 
    1111SUIL_MAJOR_VERSION = '0' 
    1212 
Note: See TracChangeset for help on using the changeset viewer.