Add rwlock_destroy and mutex_{init,destroy} imports

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Add XGLVUnregisterCloseDisplayCallbacks()

This will be called by x11glvnd clients to clean up any installed
callbacks on library teardown.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Remove a duplicate declaration

dispatchStubListGeneration was declared twice in GLdispatch.c,
so delete one of the declarations.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Track number of clients using GLdispatch

Theoretically multiple clients (libGLX and a future libEGL) may call
into __glDispatchInit() to set up dispatching, and we will want to
refcount GLdispatch to determine when dispatch teardown should occur.
So replace the global boolean 'initialized' with a counter
'clientRefcount' which tracks the number of clients using GLdispatch.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Add __glDispatch{Fini,Reset}()

__glDispatchFini() is called by a GLdispatch client to clean up
GLdispatch-internal state when the client is done using GLdispatch
functionality.

__glDispatchReset() is called by a GLdispatch client to determine
whether fork recovery is needed, and handle the fork if necessary.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Add LKDHASH_TEARDOWN() macro to handle hash table cleanup

This macro frees all entries in a locked hash table, and either
re-initializes the table's lock for fork recovery, or destroys the
lock, in which case the hash table is fully torn down and must be
re-initialized before it can be used.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Call into GLdispatch to lose current before a thread is destroyed

Without this, the current context accounting in GLdispatch can get
confused if a thread is destroyed while a context is still current
to that thread.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Fix issues with {Track,Untrack}CurrentContext()

- Don't clear the current TSD entry when UntrackCurrentContext() is
  called.  The TSD entry already contains the correct current context when
  it is set by TrackCurrentContext() prior to the call to
  UntrackCurrentContext().

- In the comment above UntrackCurrentContext(), delete an obsolete TODO.

- If make current fails, re-track the old context before returning.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Don't pass a NULL filename into dlopen(3).

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Implement fork-handling and library teardown paths

- Define a function __glXThreadInitialize() which gets called when
entering any GLX entrypoint, or when __glXGetDynDispatch() is called
by a vendor-provided GLX extension entrypoint.  This function detects
if a fork occurred since the last entrypoint was called, and performs
fork recovery if needed.

- Implement __glXFini() so that libGLX cleans up allocated resources
when it is unloaded.

These paths make heavy use of the LKDHASH_TEARDOWN() macro that was
implemented in a previous commit.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
[libglx] Replace {Track,Untrack}CurrentContext() with UpdateCurrentContext()

Instead of using separate functions to add and remove functions from the
global hash table of current contexts, use a single function which
handles:

- adding the new context and removing the old context from the global
  hash table
- initializing the tsdContextKey (if called for the first time) and
  updating the tsdContextKey for this thread to contain the new context

This function does _not_ handle removing a screen <-> context mapping if
the old context will be destroyed after it loses current; instead, it
simply returns a flag, needsUnmap, which is expected to be handled by
the caller.

Also, update __glXAPITeardown() to clean up screen <-> context mappings
as needed while entries are being removed from the current context hash.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
[libglx] Update ABI to notify vendors of X errors, fix spec compliance issue

This commit adds a new vendor callback, notifyError(), for notifying a
vendor library when an X error should be generated.  This allows the
vendor to perform any needed error recovery and to generate the error.

In MakeContextCurrentInternal(), check for:

    (context && (draw == None || read == None)) ||
    (!context && (draw != None || read != None))

and call notifyError() on an appropriate vendor to generate BadMatch
before returning False.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
[libglxmapping] Don't clear out mapping hashtables on a fork

Mappings defined in the parent should remain valid in the child process,
so don't clear out mappings after a fork since they may be needed for
GLX calls made in the child.

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>