Comment 50 for bug 86103

Revision history for this message
In , Wez (wez) wrote :

(In reply to comment #15)
> > The application has a little code in it to talk to a particular X extension via
> > the installed "Xlib". With Xlib, this works fine whether Xlib is XTHREAD-ed or
> > not - the extension client-side code in the application is built with XTHREADS
> [from your later reply, "without XTHREADS"]
> > and so does not attempt to call any locking functions. Because the application
> > never calls XInitThreads(), Xlib doesn't create locking structures for
> > displays, which routines like _XReply() assume means that locking isn't
> > required.
> Not correct. If your code builds without XTHREADS, _XReply won't even *try* to
> use locking functions if available.
[snip]

I'm afraid that you are mistaken. _XReply() is implemented in Xlib - whether or not it attempts to perform locking depends upon whether Xlib was build with XTHREADS defined, not on the calling code.

> This means that if Xlib, or other
> extension libraries, or any other component linked into your application *does*
> use XTHREADS, it will not work. If you want to build without XTHREADS, you
> need to ship all the rest of the libraries you need without XTHREADS, either by
> statically linking or by shipping your own copies of shared libraries.

I've never yet seen a single-threaded X application that is built with XTHREADS defined, yet you seem to be saying that running such an application against an XTHREADS "Xlib" isn't supported.

> > > Because building with XTHREADS or not determines how the ABI is managed.
> >
> > Can you give an example of what you mean by that? An admittedly brief glance
> > at Xlib suggests that XTHREADS-controlled APIs such as LockDisplay() boil down
> > to a check for locking structures followed by a per-display lock-function call,
> > and that those structures default to null, even for non-XTHREADS builds, and
> > are filled out only when XInitThreads() succeeds. If that were true, it would
> > always be safe to build an extension library with XTHREADS defined, incurring
> > only the minor performance hit of a potentially unnecessary pointer test each
> > Lock/UnlockDisplay(), in return for compatibility with both XTHREADS &
> > non-XTHREADS Xlib/XCB.
> And in fact new Xlib, with Xlib/XCB, does always #define XTHREADS.
> To answer your first question: the ABI of Xlib includes how you call its
> functions and manipulate its data structures, and the Xlibint macros define how
> you do that. Having XTHREADS defined or not defined changes this, and thus
> changes the ABI of Xlib.

In particular it changes LockDisplay() & UnlockDisplay() from being no-ops to checking for per-display lock_fns & using them if present. Because Displays always have a lock_fns field regardless of whether XTHREADS is defined, the XTHREADS-ed LockDisplay() & UnlockDisplay() implementations are safe to use even with non-XTHREADS "Xlib". It's only when the macros & members whose names start with an underscore, e.g. _XLockMutex(), are used that a *requirement* for the XTHREADS-ed "Xlib" ABI is created.

> > The problem appears to be that XCB's locking design assumes that calling code
> > will always call the display's "Xlib" lock & unlock functions if they are
> > present, regardless of whether the application had previously called
> > XInitThreads().
> Correct. Xlib/XCB provides an Xlib with XTHREADS defined. You may not use it
> from code built without XTHREADS defined. If you do so it will break. The
> same applies to any other Xlib built with XTHREADS. Xlib/XCB does not provide
> an Xlib without XTHREADS defined.

No, I'm afraid that's not true. Non-XInitThreads() code which only makes use of the LockDisplay() & UnlockDisplay() macros, and not of any other XTHREADS-ABI features, will work with Xlib whether Xlib is XTHREADS-ed or XTHREADS-less. Xlib only provides LockDisplay() & UnlockDisplay() implementations for Displays if XInitThreads() has been called - no XInitThreads(), no lock functions. The same code will fail with XCB because XCB defines Display locking & unlocking functions regardless of whether XInitThreads() is called, and requires the caller to use them.

> Yes, breakage will occur if you call an XTHREADS Xlib such as Xlib/XCB using
> the non-XTHREADS ABI.

No, I'm afraid it won't, for the reasons described above. There are trivial examples to illustrate this.

It seems that building extension client-side code with XTHREADS defined & which doesn't try to use the "private" XTHREADS-ABI macros & members is sufficient to make it XTHREADS & non-XTHREADS compatible.

I'm basing all of this on examination of the libX11 code & headers, of course - could someone point me to the official ABI document?

Thanks!