GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Wed Nov 26, 2014 6:39 pm

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: "Fatal IO Error 11" when I try to call gdk_draw_pixbuf()
PostPosted: Thu Jul 14, 2011 11:24 am 
Offline
Familiar Face

Joined: Tue Apr 12, 2011 12:48 pm
Posts: 8
Location: PL
I write my application in C++. One thread is responsible for drawing things on the GtkDrawingArea. I use double-buffering: draw on pixmap and redraw drawing area when it is necessarry. The class operating this thread have a queue of commands like: DRAW_ALL, SCHEME_LEFT, REFRESH_ICON_STATE etc. Thread at some intervals make new commands from main commands and call them.

For example: DRAW_ALL means DrawRectangle and DrawPixbuf. DrawRectangle - fulfils the whole pixmap with the colour of background. DrawPixbuf - draws pixbuf loaded from GtkImage (loaded from file).

DrawRectangle - works ever. DrawPixbuf - sometimes works correctly, sometimes suspends the thread, sometimes causes fatal error:
Code:
program: Fatal IO error 11 (Zasoby chwilowo niedostępne) on X server :0.0.

I have Ubuntu, Polish version. Zasoby (...) means "Resources temporary unavailable".

call stack:
Code:
Thread [3] 8948 (Suspended : Signal : SIGABRT:Aborted)   
   __kernel_vsyscall() at 0xb7fe2430   
   *__GI_raise() at raise.c:64 0xb6c9a651   
   *__GI_abort() at abort.c:92 0xb6c9da82   
   *__GI___assert_fail() at assert.c:81 0xb6c93718   
   0xb6b54a63   
   _XReply() at 0xb6b54fb6   
   XSync() at 0xb6b48847   
   gdk_flush() at 0xb7bac428   
   0xb7b7a005   
   0xb7b7a321   
   0xb7baa3af   
   gdk_draw_pixbuf() at 0xb7b73b1f   
   gdk_draw_pixbuf() at 0xb7b73b1f   
   SchemeDrawPixbuf::make() at SchematDrawerCommands.cpp:426 0x8142f2a   
   SchematDrawer::Make() at SchematDrawer.cpp:199 0x814014f   
   SchematDrawer::Work() at SchematDrawer.cpp:75 0x813ff1a   
   functionOfPosixThreadMain() at posix_thread.cpp:65 0x813f6bd   
   functionOfPosixThread() at posix_thread.cpp:75 0x813f70c   
   start_thread() at pthread_create.c:300 0xb772896e   
   clone() at clone.S:130 0xb6d3da4e   



Some code:
Code:
void SchemeDrawRectangle::make()
{
   rrout<<"void SchemeDrawRectangle::make()\tBEGIN\n" ;
   SchematDrawer::TempSchemeValues &values = schemeDrawer->tempSchemeValues ;
   if((values.flag&255)==255)
   {
      GdkGC * gc = values.drawingArea->
            style->bg_gc[GTK_WIDGET_STATE(values.drawingArea)] ;
      rrout<<"gc="<<gc<<"\n" ;

      rrout<<"da="<<values.drawingAreaWidth<<"x"<<values.drawingAreaHeight<<"\n" ;

      int ww,hh;
      gdk_drawable_get_size(values.pixmapMain, &ww, &hh) ;
      rrout<<"pixmap main: "<<values.pixmapMain<<", "<<ww<<"x"<<hh<<"\n" ;
      gdk_drawable_get_size(values.pixmapBackground, &ww, &hh) ;
      rrout<<"pixmap back: "<<values.pixmapBackground<<", "<<ww<<"x"<<hh<<"\n" ;

      gdk_draw_rectangle(values.pixmapMain,   gc, TRUE, 0,0,
            values.drawingAreaWidth, values.drawingAreaHeight) ;
      gdk_draw_rectangle(values.pixmapBackground, gc, TRUE, 0,0,
            values.drawingAreaWidth, values.drawingAreaHeight) ;
   }
   else
   {
      rrout<<"\tflag == "<<values.flag<<"\n" ;
   }
   rrout<<"void SchemeDrawRectangle::make()\tEND\n" ;
} //IT WORKS

//[...]

void SchemeDrawPixbuf::make()
{
   rrout<<"void SchemeDrawPixbuf::make()\tBEGIN\n" ;
   SchematDrawer *schemeDrawer = SchematDrawer::Instance() ;

   int x0 = (schemeDrawer->tempSchemeValues.drawingAreaWidth-width)/2 ;
   int y0 = (schemeDrawer->tempSchemeValues.drawingAreaHeight-height)/2 ;

   rrout<<"da_width="<<schemeDrawer->tempSchemeValues.drawingAreaWidth<<
         ", width="<<width<<", x0="<<x0<<"\n" ;
   rrout<<"da_height="<<schemeDrawer->tempSchemeValues.drawingAreaHeight<<
         ", height="<<height<<", y0="<<y0<<"\n" ;

   GdkGC * gc = schemeDrawer->tempSchemeValues.drawingArea->
         style->bg_gc[GTK_WIDGET_STATE(schemeDrawer->tempSchemeValues.drawingArea)] ;

   rrout<<"gc="<<gc<<"\n" ;
   rrout<<"pixbuf="<<pixbuf<<", "<<
         gdk_pixbuf_get_width(pixbuf)<<"x"<<gdk_pixbuf_get_height(pixbuf)<<"\n" ;
   rrout<<(GDK_IS_PIXBUF(pixbuf)?"YES":"NO")<<"\n" ;

   int ww,hh;
   gdk_drawable_get_size(schemeDrawer->tempSchemeValues.pixmapMain, &ww, &hh) ;
   rrout<<"pixmap main: "<<schemeDrawer->tempSchemeValues.pixmapMain<<", "<<ww<<"x"<<hh<<"\n" ;
   rrout<<(GDK_IS_PIXMAP(schemeDrawer->tempSchemeValues.pixmapMain)?"YES":"NO")<<"\n" ;
   gdk_drawable_get_size(schemeDrawer->tempSchemeValues.pixmapBackground, &ww, &hh) ;
   rrout<<"pixmap back: "<<schemeDrawer->tempSchemeValues.pixmapBackground<<", "<<ww<<"x"<<hh<<"\n" ;
   rrout<<(GDK_IS_PIXMAP(schemeDrawer->tempSchemeValues.pixmapBackground)?"YES":"NO")<<"\n" ;

    gdk_draw_pixbuf (schemeDrawer->tempSchemeValues.pixmapMain, gc,
            pixbuf, 0, 0, x0, y0, width, height, GDK_RGB_DITHER_NONE, 0, 0);
    rrout<<"narysowano na main\n" ;
    gdk_draw_pixbuf (schemeDrawer->tempSchemeValues.pixmapBackground, gc,
            pixbuf, 0, 0, x0, y0, width, height, GDK_RGB_DITHER_NONE, 0, 0);
    rrout<<"narysowano na back\n" ;
   rrout<<"void SchemeDrawPixbuf::make()\tEND\n" ;
}


log:
Code:
void SchemeDrawPixbuf::make()   BEGIN
da_width=1115, width=919, x0=98
da_height=690, height=689, y0=0
gc=0x9269530
pixbuf=0x92c16b0, 919x689
YES
pixmap main: 0x928beb0, 1115x690
YES
pixmap back: 0x928be98, 1115x690
YES
fhome: Fatal IO error 11 (Zasoby chwilowo niedostępne) on X server :0.0.



thanks for any answer.


Top
 Profile  
 
 Post subject: Re: "Fatal IO Error 11" when I try to call gdk_draw_pixbuf()
PostPosted: Thu Jul 14, 2011 1:47 pm 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 780
Location: UK
Some one else has asked a similar question, with the same problem, but using C. GTK+ is thread aware but not thread safe. You will need to use the GDK mutex to lock calls to to GTK/GDK and initialise the threading system. Or better still have all the GTK/GDK drawing done in the main thread and have your worker threads communicate to the main thread to tell it what to draw.

Errol.

_________________
E.


Top
 Profile  
 
 Post subject: Re: "Fatal IO Error 11" when I try to call gdk_draw_pixbuf()
PostPosted: Thu Jul 14, 2011 3:36 pm 
Offline
Familiar Face

Joined: Tue Apr 12, 2011 12:48 pm
Posts: 8
Location: PL
But I've provide locks for PixMap operations for one thread in time by using pthread_mutex_t mutex.

Drawing: Pixmaps to DrawingArea:
Code:
gint obszar_exp_ev(GtkWidget *kontrolka, GdkEventExpose *zdarzenie)
{
   ReportBegin("gint obszar_exp_ev(GtkWidget *kontrolka, GdkEventExpose *zdarzenie)") ;
   CLogFun::Inkr(17) ;
   
   schematDrawer->LockMutex() ;

    GdkDrawable* rysunek = obszar->window ;

    gdk_draw_pixmap(rysunek, obszar->style->fg_gc[GTK_WIDGET_STATE(obszar)],
        pixmap_2b_main, 0, 0, 0, 0, ob_szer, ob_wys);

    schematDrawer->UnlockMutex() ;
    ReportEnd("gint obszar_exp_ev(GtkWidget *kontrolka, GdkEventExpose *zdarzenie)") ;
    return FALSE ;
}

static gint obszar_conf_ev(GtkWidget *kontrolka, GdkEventConfigure *zdarzenie)
{
   rrout<<"static gint obszar_conf_ev(GtkWidget *kontrolka, GdkEventConfigure *zdarzenie)\tBEGIN\n" ;
   CLogFun::Inkr(18) ;
   
   schematDrawer->LockMutex() ;
   
    if (pixmap_2b_main)
    {
       rrprintf("pixmap main unref!\n") ;
        gdk_pixmap_unref(pixmap_2b_main) ;
    }
    if (pixmap_2b_main_tlo)
    {
       rrprintf("pixmap back unref!\n") ;
        gdk_pixmap_unref(pixmap_2b_main_tlo) ;
    }

    GdkDrawable* rysunek = obszar->window ;

    pixmap_2b_main = gdk_pixmap_new(rysunek, ob_szer, ob_wys, -1) ;
    pixmap_2b_main_tlo = gdk_pixmap_new(rysunek, ob_szer, ob_wys, -1) ;

    czyKwadrat = true ;

   schematDrawer->UnlockMutex() ;
   
   schematDrawer->setPixmaps(pixmap_2b_main, pixmap_2b_main_tlo) ;
    rrprintf("przed refresh linia %d z pliku %s\n",__LINE__, __FILE__) ;
   schematDrawer->refreshSchemeAction(DRAW_ALL) ;
   rrprintf("po refresh linia %d z pliku %s\n",__LINE__, __FILE__) ;

   rrout<<"static gint obszar_conf_ev(GtkWidget *kontrolka, GdkEventConfigure *zdarzenie)\tEND\n" ;
    return TRUE ;
}


Second thread work() function:
Code:
void SchematDrawer::Work()
{
   SetUp() ;
   LockMutex() ;
   if(prepareCommands.size())
   {
      RemoveRepeatedCommands() ;
      Prepare() ;
      Make() ;
   }
   UnlockMutex() ;
   TearDown() ;
}


lock and unlock functions:
Code:
      inline void LockMutex()
      {
         if(pthread_mutex_lock(&schemeDrawerMutex)!=0)
         {
            MutexException exc ;
            throw exc ;
         }
      }
      inline void UnlockMutex()
      {
         if(pthread_mutex_unlock(&schemeDrawerMutex)!=0)
         {
            MutexException exc ;
            throw exc ;
         }
      }


Top
 Profile  
 
 Post subject: Re: "Fatal IO Error 11" when I try to call gdk_draw_pixbuf()
PostPosted: Thu Jul 14, 2011 4:18 pm 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 780
Location: UK
Hi,

What you have done is create your own locking mechanism, and not used the GDK mutex locking system.

Have a read of manual linked below, which explains about the GDK lock and initialisation of the threading system.
http://developer.gnome.org/gdk/unstable/gdk-Threads.html
With out initialising the threading in GDK you will not be able to call GTK/GDK functions from multiple threads. You must use the GDK lock to protect calls to GTK/GDK functions, do not create your own as that does not do the correct protection. Also note all of this will not work on a system running Microsoft Windows.

I would advise that you have all the GTK/GDK calls done in one thread (the one gtk_main() was called in), and have the other threads communicate with the main thread. This would then avoid the need to have any locking.

Errol.

_________________
E.


Top
 Profile  
 
 Post subject: Re: "Fatal IO Error 11" when I try to call gdk_draw_pixbuf()
PostPosted: Fri Jul 15, 2011 7:29 am 
Offline
Familiar Face

Joined: Tue Apr 12, 2011 12:48 pm
Posts: 8
Location: PL
thank you for ayour advice! i'll apply it. i didn't realize that i must use gdk threading mechanism.

ps. my application mustn't work on windows. it is designed only for linux


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google Adsense [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group