nanogui: multi-threaded app: problem and suggestion; patch


Previous by date: 11 Aug 2005 07:32:34 +0100 fix for gcc compiler version; patch, Petr Ovtchenkov
Next by date: 11 Aug 2005 07:32:34 +0100 Re: FLNX, Van Rafelghem, Dominique
Previous in thread:
Next in thread: 11 Aug 2005 07:32:34 +0100 Re: multi-threaded app: problem and suggestion; patch, Petr Ovtchenkov

Subject: multi-threaded app: problem and suggestion; patch
From: Petr Ovtchenkov ####@####.####
Date: 11 Aug 2005 07:32:34 +0100
Message-Id: <200508111032.31592.ptr@island.plnet.ru>

The design of nanoX lead to problems during usage in multi-threaded 
applications. Let's consider:

thread 1 (windows creation):
----------------------------------------------

mwid = GrNewWindow( parent.mwid, _g._x, _g._y, _g._w, _g._h, /* _b._w */2, 
_bg, /* _b._c */ RED );
  if ( ev_mask != 0 ) {
    GrSelectEvents( mwid, ev_mask );
  }
  GrMapWindow( mwid );
  GrFlush();
....
  GrDrawImageToFit( mwid, _gc, _g.x(), _g.y(), _g.width(), _g.height(), 
_i2->id() );
....
mwid2 = GrNewWindow( parent.mwid, _g._x, _g._y, _g._w, _g._h, /* _b._w */2, 
_bg, /* _b._c */ RED );
  if ( ev_mask != 0 ) {
    GrSelectEvents( mwid2, ev_mask );
  }
  GrMapWindow( mwid2 );
  GrFlush();

  GrCreateFont( (GR_CHAR *)"koi8x13.pcf.gz", 0, 0 );
  GrSetGCForeground( _gc, fg );
  GrSetGCBackground( _gc, bg );
  GrSetGCFont( _gc, _fid );
....
  GrText( imwid2, _gc, x, y, (void *)i->data(), i->size(), GR_TFASCII );
----------------------------------------------


thread 2 (main loop):
----------------------------------------------

GR_EVENT ev;

while ( !some_condition ) {
  GrGetNextEvent(&ev);

  switch ( ev.type ) {
    case GR_EVENT_TYPE_ERROR:
      /* cerr << "GR_EVENT_TYPE_ERROR" << endl; */
      break;
    case GR_EVENT_TYPE_NONE:
      /* cerr << "GR_EVENT_TYPE_NONE" << endl; */
      break;
    case GR_EVENT_TYPE_EXPOSURE:
      /*
      {
        __impl::Locker lock( map_lk );
        Event_base<NX_EvExposure> event( EV_NX_EXPOSURE );
        // cerr << mw_stem_map[ev.exposure.wid] << endl;
        event.dest( mw_stem_map[ev.exposure.wid] );
        event.value() = ev.exposure;
        dummy.Send( event );

        cerr << "GR_EVENT_TYPE_EXPOSURE" << endl;
      }
      */
      break;
   ....
  }
}
----------------------------------------------

This code lead to deadlock, due to all Window-related calls lock on mutex when 
perform critical operation under global data in thread 1, and GrGetNextEvent 
do lock on same mutex and call select() that wait event:

GR_GC_ID 
GrNewGC(void)
{
...
	LOCK(&nxGlobalLock);
...
	UNLOCK(&nxGlobalLock);
...
}


...

void
GrServiceSelect(void *rfdset, GR_FNCALLBACKEVENT fncb)
{
...
	LOCK(&nxGlobalLock);
...
	select(setsize+1, &rfds, NULL, NULL, timeout ? &to : NULL));
...
	UNLOCK(&nxGlobalLock);
}


The same behavior on server side (this significant in case when you link nanoX 
server inside application).

The solution: when you waiting on select() lock not required.

In attached patch I add XXGrEvent( GR_EVENT *ev ) functions, that used instead 
of GrGetNextEvent. This function on src/nanox/client.c is clean (it in use 
for client-server approach), while code in src/nanox/srvfunc.c and 
src/nanox/srvmain.c is like hack and revision required.

Patch is against current CVS.

Bests,

   - ptr


[Content type text/x-diff not shown. Download]

Previous by date: 11 Aug 2005 07:32:34 +0100 fix for gcc compiler version; patch, Petr Ovtchenkov
Next by date: 11 Aug 2005 07:32:34 +0100 Re: FLNX, Van Rafelghem, Dominique
Previous in thread:
Next in thread: 11 Aug 2005 07:32:34 +0100 Re: multi-threaded app: problem and suggestion; patch, Petr Ovtchenkov


Powered by ezmlm-browse 0.20.