aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_internal.h
diff options
context:
space:
mode:
authorIan Jackson <ian.jackson@eu.citrix.com>2013-01-24 12:47:52 +0000
committerIan Jackson <ian.jackson@eu.citrix.com>2013-01-24 12:47:52 +0000
commitbc7e8a2a813e0acfddd62fa5b6c4571ada8d1cd1 (patch)
tree6e0f050e1e7922805cdba23a0e87494972b8efec /tools/libxl/libxl_internal.h
parent9f0443bafbab97831e5c99553bf9f0805537f3fc (diff)
downloadxen-bc7e8a2a813e0acfddd62fa5b6c4571ada8d1cd1.tar.gz
xen-bc7e8a2a813e0acfddd62fa5b6c4571ada8d1cd1.tar.bz2
xen-bc7e8a2a813e0acfddd62fa5b6c4571ada8d1cd1.zip
libxl: fix stale fd event callback race
Because there is not necessarily any lock held at the point the application (eg, libvirt) calls libxl_osevent_occurred_timeout and ..._fd, in a multithreaded program those calls may be arbitrarily delayed in relation to other activities within the program. libxl therefore needs to be prepared to receive very old event callbacks. Arrange for this to be the case for fd callbacks. This requires a new layer of indirection through a "hook nexus" struct which can outlive the libxl__ev_foo. Allocation and deallocation of these nexi is mostly handled in the OSEVENT macros which wrap up the application's callbacks. Document the problem and the solution in a comment in libxl_event.c just before the definition of struct libxl__osevent_hook_nexus. There is still a race relating to libxl__osevent_occurred_timeout; this will be addressed in the following patch. Reported-by: Bamvor Jian Zhang <bjzhang@suse.com> Cc: Bamvor Jian Zhang <bjzhang@suse.com> Cc: Ian Campbell <Ian.Campbell@citrix.com> Tested-by: Jim Fehlig <jfehlig@suse.com> Acked-by: Jim Fehlig <jfehlig@suse.com> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/libxl/libxl_internal.h')
-rw-r--r--tools/libxl/libxl_internal.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 0b38e3e8bc..1567b4b03f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -136,6 +136,8 @@ typedef struct libxl__gc libxl__gc;
typedef struct libxl__egc libxl__egc;
typedef struct libxl__ao libxl__ao;
typedef struct libxl__aop_occurred libxl__aop_occurred;
+typedef struct libxl__osevent_hook_nexus libxl__osevent_hook_nexus;
+typedef struct libxl__osevent_hook_nexi libxl__osevent_hook_nexi;
_hidden void libxl__alloc_failed(libxl_ctx *, const char *func,
size_t nmemb, size_t size) __attribute__((noreturn));
@@ -163,7 +165,7 @@ struct libxl__ev_fd {
libxl__ev_fd_callback *func;
/* remainder is private for libxl__ev_fd... */
LIBXL_LIST_ENTRY(libxl__ev_fd) entry;
- void *for_app_reg;
+ libxl__osevent_hook_nexus *nexus;
};
@@ -178,7 +180,7 @@ struct libxl__ev_time {
int infinite; /* not registered in list or with app if infinite */
LIBXL_TAILQ_ENTRY(libxl__ev_time) entry;
struct timeval abs;
- void *for_app_reg;
+ libxl__osevent_hook_nexus *nexus;
};
typedef struct libxl__ev_xswatch libxl__ev_xswatch;
@@ -329,6 +331,8 @@ struct libxl__ctx {
libxl__poller poller_app; /* libxl_osevent_beforepoll and _afterpoll */
LIBXL_LIST_HEAD(, libxl__poller) pollers_event, pollers_idle;
+ LIBXL_SLIST_HEAD(libxl__osevent_hook_nexi, libxl__osevent_hook_nexus)
+ hook_fd_nexi_idle, hook_timeout_nexi_idle;
LIBXL_LIST_HEAD(, libxl__ev_fd) efds;
LIBXL_TAILQ_HEAD(, libxl__ev_time) etimes;