Add xcb_xlib_lock and xcb_xlib_unlock, a special-purpose two-level recursive lock just for libX11.
This commit is contained in:
parent
57b0cd8fea
commit
40589db812
|
@ -59,6 +59,18 @@ static int set_fd_flags(const int fd)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _xcb_xlib_init(_xcb_xlib *xlib)
|
||||||
|
{
|
||||||
|
xlib->lock = 0;
|
||||||
|
pthread_cond_init(&xlib->cond, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _xcb_xlib_destroy(_xcb_xlib *xlib)
|
||||||
|
{
|
||||||
|
pthread_cond_destroy(&xlib->cond);
|
||||||
|
}
|
||||||
|
|
||||||
static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info)
|
static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info)
|
||||||
{
|
{
|
||||||
static const char pad[3];
|
static const char pad[3];
|
||||||
|
@ -215,6 +227,7 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info)
|
||||||
if(!(
|
if(!(
|
||||||
set_fd_flags(fd) &&
|
set_fd_flags(fd) &&
|
||||||
pthread_mutex_init(&c->iolock, 0) == 0 &&
|
pthread_mutex_init(&c->iolock, 0) == 0 &&
|
||||||
|
_xcb_xlib_init(&c->xlib) &&
|
||||||
_xcb_in_init(&c->in) &&
|
_xcb_in_init(&c->in) &&
|
||||||
_xcb_out_init(&c->out) &&
|
_xcb_out_init(&c->out) &&
|
||||||
write_setup(c, auth_info) &&
|
write_setup(c, auth_info) &&
|
||||||
|
@ -239,6 +252,7 @@ void xcb_disconnect(xcb_connection_t *c)
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
|
|
||||||
pthread_mutex_destroy(&c->iolock);
|
pthread_mutex_destroy(&c->iolock);
|
||||||
|
_xcb_xlib_destroy(&c->xlib);
|
||||||
_xcb_in_destroy(&c->in);
|
_xcb_in_destroy(&c->in);
|
||||||
_xcb_out_destroy(&c->out);
|
_xcb_out_destroy(&c->out);
|
||||||
|
|
||||||
|
@ -258,6 +272,12 @@ void _xcb_conn_shutdown(xcb_connection_t *c)
|
||||||
void _xcb_lock_io(xcb_connection_t *c)
|
void _xcb_lock_io(xcb_connection_t *c)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&c->iolock);
|
pthread_mutex_lock(&c->iolock);
|
||||||
|
while(c->xlib.lock)
|
||||||
|
{
|
||||||
|
if(pthread_equal(c->xlib.thread, pthread_self()))
|
||||||
|
break;
|
||||||
|
pthread_cond_wait(&c->xlib.cond, &c->iolock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _xcb_unlock_io(xcb_connection_t *c)
|
void _xcb_unlock_io(xcb_connection_t *c)
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "xcbxlib.h"
|
#include "xcbxlib.h"
|
||||||
#include "xcbint.h"
|
#include "xcbint.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
unsigned int xcb_get_request_sent(xcb_connection_t *c)
|
unsigned int xcb_get_request_sent(xcb_connection_t *c)
|
||||||
{
|
{
|
||||||
if(c->has_error)
|
if(c->has_error)
|
||||||
|
@ -39,3 +41,22 @@ pthread_mutex_t *xcb_get_io_lock(xcb_connection_t *c)
|
||||||
return 0;
|
return 0;
|
||||||
return &c->iolock;
|
return &c->iolock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xcb_xlib_lock(xcb_connection_t *c)
|
||||||
|
{
|
||||||
|
_xcb_lock_io(c);
|
||||||
|
assert(!c->xlib.lock);
|
||||||
|
c->xlib.lock = 1;
|
||||||
|
c->xlib.thread = pthread_self();
|
||||||
|
_xcb_unlock_io(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcb_xlib_unlock(xcb_connection_t *c)
|
||||||
|
{
|
||||||
|
_xcb_lock_io(c);
|
||||||
|
assert(c->xlib.lock);
|
||||||
|
assert(pthread_equal(c->xlib.thread, pthread_self()));
|
||||||
|
c->xlib.lock = 0;
|
||||||
|
pthread_cond_broadcast(&c->xlib.cond);
|
||||||
|
_xcb_unlock_io(c);
|
||||||
|
}
|
||||||
|
|
18
src/xcbint.h
18
src/xcbint.h
|
@ -113,6 +113,15 @@ int _xcb_in_read(xcb_connection_t *c);
|
||||||
int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread);
|
int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread);
|
||||||
|
|
||||||
|
|
||||||
|
/* xcb_xlib.c */
|
||||||
|
|
||||||
|
typedef struct _xcb_xlib {
|
||||||
|
int lock;
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
} _xcb_xlib;
|
||||||
|
|
||||||
|
|
||||||
/* xcb_xid.c */
|
/* xcb_xid.c */
|
||||||
|
|
||||||
typedef struct _xcb_xid {
|
typedef struct _xcb_xid {
|
||||||
|
@ -150,6 +159,7 @@ struct xcb_connection_t {
|
||||||
|
|
||||||
/* I/O data */
|
/* I/O data */
|
||||||
pthread_mutex_t iolock;
|
pthread_mutex_t iolock;
|
||||||
|
_xcb_xlib xlib;
|
||||||
_xcb_in in;
|
_xcb_in in;
|
||||||
_xcb_out out;
|
_xcb_out out;
|
||||||
|
|
||||||
|
@ -159,8 +169,6 @@ struct xcb_connection_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
void _xcb_conn_shutdown(xcb_connection_t *c);
|
void _xcb_conn_shutdown(xcb_connection_t *c);
|
||||||
void _xcb_lock_io(xcb_connection_t *c);
|
|
||||||
void _xcb_unlock_io(xcb_connection_t *c);
|
|
||||||
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,4 +180,10 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info);
|
||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* xcb_conn.c symbols visible to xcb-xlib */
|
||||||
|
|
||||||
|
void _xcb_lock_io(xcb_connection_t *c);
|
||||||
|
void _xcb_unlock_io(xcb_connection_t *c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,4 +36,7 @@ unsigned int xcb_get_request_sent(xcb_connection_t *c);
|
||||||
|
|
||||||
pthread_mutex_t *xcb_get_io_lock(xcb_connection_t *c);
|
pthread_mutex_t *xcb_get_io_lock(xcb_connection_t *c);
|
||||||
|
|
||||||
|
void xcb_xlib_lock(xcb_connection_t *c);
|
||||||
|
void xcb_xlib_unlock(xcb_connection_t *c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue