Sun's Xlib threading fixes

1234757: XInitThreads needs to be made less restrictive

Description

This is a RFE to enhance XInitThreads so that it may be called:

For Example, in order for XIL 1.3 to be MT HOT, it must be able to make the call to XInit Threads, even if the client has already made other Xlib calls.

Evaluation

[I couldn't find this for this bug.]

Fix

Fix integrated to Solaris 2.6, June 1996 in OpenDis.c & locking.c.
Patch: 1234757.txt

4010755: SEGV in XFindContext if XInitThreads has been enabled

Description

XIL enables MT-SAFE Xlib by calling XInitThreads prior to using Xlib in an MT-HOT fashion. This causes a SEGV when running sdtimage because Xlib appears to call mutex_lock on a NULL mutex in XFindContext().

To reproduce:

setenv LD_LIBRARY_PATH $XILHOME/lib:$LD_LIBRARY_PATH
setenv XIL_DISPLAY SUNWxlib

/usr/dt/bin/sdtimage /shared/xil/data/images/tiff/Parrots.tiff

A core file will be generated that has the following stack trace:

t@0 l@1 <1> where
=>[1] _lock_try_adaptive(0x0, 0x1c594, 0xefffe2dd, 0xc79f0, 0xef19f3d4, 0xef353dd0), at 0xeeba410c
  [2] _ti_pthread_mutex_lock(0x0, 0xeebb45cc, 0xc79f0, 0xef3f0034, 0xef19f3d4, 0xef30f404), at 0xeeb98048
  [3] XFindContext(0x9e3a8, 0xa77a0, 0xffffffff, 0xefffdb4c, 0xef37a26c, 0xeee93130), at 0xef30f404
  [4] _XmGetWidgetExtData(0xa77a0, 0x3, 0xef3f0034, 0x0, 0xa77a0, 0xef43a82c), at 0xef439844
  [5] _XmGetFocusData(0xa77a0, 0xef573e18, 0xefffdfa8, 0xc79f0, 0xf9178, 0x0), at 0xef478304
  [6] _XmNavigSetValues(0xefffe2c8, 0xefffdfa8, 0xc79f0, 0xef573e18, 0xefffdd68, 0x0), at 0xef47a2cc
  [7] SetValues(0xefffe2c8, 0xefffdfa8, 0xc79f0, 0xf9178, 0xefffdd68, 0xef573e18), at 0xef476fc0
  [8] CallSetValues(0x0, 0xefffe2c8, 0xefffdfa8, 0xc79f0, 0xf9178, 0xef476e94), at 0xef3c583c
  [9] CallSetValues(0x0, 0xefffe2c8, 0xefffdfa8, 0xc79f0, 0xf9178, 0x3), at 0xef3c57d4
  [10] XtSetValues(0xef3f3b34, 0xf9178, 0xef3f3b30, 0x0, 0x9db48, 0xef57f66c), at 0xef3c5e00
  [11] XtVaSetValues(0xc79f0, 0x0, 0x0, 0x98b54, 0x200, 0x99273), at 0xef3d9ea0
  [12] resize_canvas(0x9a9a0, 0x99273, 0x9a998, 0x98b54, 0x9a800, 0x9a323), at 0x4d9b0
  [13] open_newfile(0x9a800, 0x9a9a0, 0x9a98c, 0x9a7e8, 0x0, 0xc6488), at 0x32564
  [14] main(0x81a34, 0x1, 0x9a7e8, 0xc6488, 0xefffef2a, 0xefffef01), at 0x2d740

Evaluation

XFindContext in Xlib was calling _XLockMutex with an uninitialized mutex lock structure. The new version of XInitThreads activates the locking functions at any time, even after displays have been created.

In this new case, the context structure was created prior to XInitThreads being invoked. As a result, the display contained an opaque pointer to this context structure, which still contained an uninitialized lock structure.

The solution was to explicitly set the lock structure pointer to NULL (as a flag) when creating the context, then check for NULL before locking. If NULL is found and threads are now enabled, then the structure gets reinitialized to the correct mutex lock structure before the lock call.

Another area besides the functions in Context.c are the functions in Xrm.c. A similar fix was added to them as well.

Fix

Fix integrated to Solaris 2.6, Jan. 97 in Context.c & Xrm.c.
Patch: 4010755.txt

4041914: Sdtimage freezes in XFilterEvent when user try to input Japanese word in "Save As" dialog

Description

1. start sdtimage in ja locale and open tiff or jpeg or raster or gif file.
2. select "Save As" in File menu.
Then "Save As" dialog opens.
3. if you use cs00 as japanese input server, type Control + Space.
Then, Japanese input mode is set , but sdtimage freezes.
You cannot input Japanese word in textfield of "Save As" dialog.
Sdtimage does not work any more.

Evaluation

The trace of sdtimage when the problem occurs is as follows:

(dbx) threads
*>    t@1  a l@1  ?()   signal SIGINT   in __sigprocmask()
      t@2  b l@2  ?()   running                 in _signotifywait()
      t@3         ?()   sleep on (unknown)      in _swtch()
      t@4  b l@4  ?()   running                 in _lwp_sema_wait()

(dbx) lwps        
*>l@1 signal SIGINT in __sigprocmask()
  l@2 running          in _signotifywait()
  l@3 running          in ___lwp_cond_wait()
  l@4 running          in _lwp_sema_wait()
  l@5 running          in _door_return()

(dbx) where
current thread: t@1
  [1] __sigprocmask(0xdf88d8e0, 0xf8df88d8, 0x87f8df88), at 0xdf88b551
  [2] __bounceself(), at 0xdf884675
  [3] _sigon(), at 0xdf8843a5
  [4] _mutex_adaptive_lock(), at 0xdf8821c3
  [5] _pthread_mutex_lock(), at 0xdf881fa4
  [6] mutex_lock(), at 0xdfbed931
  [7] _XLockDisplay(), at 0xdfd4d6cd
  [8]  at 0xdfd22839
  [9] _Ximp_RegKeyPressed(), at 0xdebebd99
  [10] _Ximp_KeypressFilter(), at 0xdebebfd4
  [11] _Ximp_XimFilter_Keypress(), at 0xdebedc27
  [12] XFilterEvent(), at 0xdfd4d0df
  [13] _XtDefaultDispatcher(), at 0xdfd80815
  [14] XtDispatchEvent(), at 0xdfd80a29
=>[15] main(argc = 2, argv = 0x8047a94), line 716 in "imagetool.c"

(dbx) where t@2
current thread: t@2
  [1] _signotifywait(0xdf808000, 0xdf8080, 0xdf80), at 0xdfbaac1c
  [2] _dynamiclwps(), at 0xdf884c09

(dbx) where t@3
current thread: t@3
  [1] _swtch(), at 0xdf88108d
  [2] _sigon(), at 0xdf8843a5
  [3] _reaper(), at 0xdf884024

(dbx) where t@4
current thread: t@4
  [1] _lwp_sema_wait(0xdf606000, 0xdf6060, 0xdf60), at 0xdfbaab61
  [2] _tdb_agent(), at 0xdf889c1d

From my examination of the problem, and a little searching about in the X11 sources. It looks like XFilterEvent(), is doing an XLockDisplay and calling the filter function, in Ximp (extract from XFilterEvent):

Bool
XFilterEvent(ev, window)
    XEvent *ev;
    Window window;
{
    ...

    LockDisplay(ev->xany.display);
    for (p = ev->xany.display->im_filters; p != NULL; p = p->next) {
    if (win == p->window) {
        if ((mask & p->event_mask) ||
        (ev->type >= p->start_type && ev->type <= p->end_type)) {
        ret = (*(p->filter))(ev->xany.display, p->window, ev,
                      p->client_data);
        UnlockDisplay(ev->xany.display);
        return(ret);
        }
    }
    UnlockDisplay(ev->xany.display);
    return(False);
}

After this also does a LockDisplay, but I think XGetWindowAttributes(), it's here, waiting for the semaphore to be released (extract from XGetWindowAttributes):

Status XGetWindowAttributes(dpy, w, attr)
     register Display *dpy;
     Window w;
     XWindowAttributes *attr;
{
    xGetGeometryReply rep;
    register xResourceReq *req;
    register int i;
    register Screen *sp;
    _XAsyncHandler async;
    _XWAttrsState async_state;

    LockDisplay(dpy);
    GetResReq(GetWindowAttributes, w, req);

    ...
    
}

I tried to remove LockDisplay/UnlockDisplay statements from XFilterEvent function and rebuilt the library. With this change, the bug was fixed. I believe this is better fix than doing UnlockDisplay/LockDisplay around XGetWindowAttributes inside XIM module, and there is no other side effect. In non-threaded environment, this change does not affect anything. XIM people told me that the input method module does not touch any of the display structure members, so it is safe to remove the locks.

Fix

Fix integrated to Solaris 2.6, July 97 in FilterEv.c.
Patch: 4041914.txt

Note: The fixes applied in X11R6.8 for bugzilla #1182 appear to be an attempt to fix the same issue in a different way.

4614834: Xlib color functions are not MT-safe

Description

In a multithreaded Xlib client:

XInitThread() is called before any X request.

If you cannot reproduce the crash with just launching ./threads4 or ./threads5, use the RTC to see the memory fault:

(dbx) check -access
access checking - ON
(dbx) run
Running: threads5 
(process id 2617)
Reading librtc.so
RTC: Enabling Error Checking...
RTC: Patching executable code.
RTC: Done patching code.
STARTING IN 1 SEC
..t@5 (l@3) signal SEGV (no mapping at the fault address) in __rtc_strcmp at 0xfe9411b8
0xfe9411b8: __rtc_strcmp+0x0008:        ldub    [%o1], %o3
Current function is LookupColor
   22                           "black", &color, &exact);

Evaluation

The cause of the problem is that in multithread environment some data in XLookupColor() and XAllocNamedColor() can be accessed/motified at same time by multi threads. Adding some lock and unlock code to make sure only one thread can access the data at one time fixed the problem.

Fix

Fix integrated to Solaris 9, Dec. 2001 in GetColor.c & LookupCol.c.
Patch: 4614834.txt


Copyright © 2005 Sun Microsystems, Inc. All rights reserved.
Last modified: Sat Jun 18 20:48:39 PDT 2005