Re: [PATCH weston v3] Copying xkb_info when creating a seat causes problems
On Fri, Sep 06, 2013 at 08:29:12AM +, Andrew Wedgbury wrote: > Sorry, I missed updating use of xkb_info in compositor-x11.c. > I've updated the patch. Argh, and I ended up applying and pushing v2 before seeing this. Oh well, I've applied the compositor-x11.c part of the patch and the x11 backend modifiers work again. thanks, Kristian > --- > src/compositor-x11.c |2 +- > src/compositor.h |5 ++-- > src/input.c | 77 > +++--- > src/text-backend.c |4 +-- > 4 files changed, 54 insertions(+), 34 deletions(-) > > diff --git a/src/compositor-x11.c b/src/compositor-x11.c > index a896612..e04ea06 100644 > --- a/src/compositor-x11.c > +++ b/src/compositor-x11.c > @@ -160,7 +160,7 @@ x11_compositor_get_keymap(struct x11_compositor *c) > static uint32_t > get_xkb_mod_mask(struct x11_compositor *c, uint32_t in) > { > - struct weston_xkb_info *info = &c->core_seat.xkb_info; > + struct weston_xkb_info *info = c->core_seat.xkb_info; > uint32_t ret = 0; > > if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID) > diff --git a/src/compositor.h b/src/compositor.h > index 6db3c61..3755650 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -398,6 +398,7 @@ struct weston_xkb_info { > int keymap_fd; > size_t keymap_size; > char *keymap_area; > + int32_t ref_count; > xkb_mod_index_t shift_mod; > xkb_mod_index_t caps_mod; > xkb_mod_index_t ctrl_mod; > @@ -468,7 +469,7 @@ struct weston_seat { > > void (*led_update)(struct weston_seat *ws, enum weston_led leds); > > - struct weston_xkb_info xkb_info; > + struct weston_xkb_info *xkb_info; > struct { > struct xkb_state *state; > enum weston_led leds; > @@ -588,7 +589,7 @@ struct weston_compositor { > > struct xkb_rule_names xkb_names; > struct xkb_context *xkb_context; > - struct weston_xkb_info xkb_info; > + struct weston_xkb_info *xkb_info; > > /* Raw keyboard processing (no libxkbcommon initialization or handling) > */ > int use_xkbcommon; > diff --git a/src/input.c b/src/input.c > index aa40b4e..78b6ead 100644 > --- a/src/input.c > +++ b/src/input.c > @@ -760,24 +760,24 @@ notify_modifiers(struct weston_seat *seat, uint32_t > serial) > /* And update the modifier_state for bindings. */ > mods_lookup = mods_depressed | mods_latched; > seat->modifier_state = 0; > - if (mods_lookup & (1 << seat->xkb_info.ctrl_mod)) > + if (mods_lookup & (1 << seat->xkb_info->ctrl_mod)) > seat->modifier_state |= MODIFIER_CTRL; > - if (mods_lookup & (1 << seat->xkb_info.alt_mod)) > + if (mods_lookup & (1 << seat->xkb_info->alt_mod)) > seat->modifier_state |= MODIFIER_ALT; > - if (mods_lookup & (1 << seat->xkb_info.super_mod)) > + if (mods_lookup & (1 << seat->xkb_info->super_mod)) > seat->modifier_state |= MODIFIER_SUPER; > - if (mods_lookup & (1 << seat->xkb_info.shift_mod)) > + if (mods_lookup & (1 << seat->xkb_info->shift_mod)) > seat->modifier_state |= MODIFIER_SHIFT; > > /* Finally, notify the compositor that LEDs have changed. */ > if (xkb_state_led_index_is_active(seat->xkb_state.state, > - seat->xkb_info.num_led)) > + seat->xkb_info->num_led)) > leds |= LED_NUM_LOCK; > if (xkb_state_led_index_is_active(seat->xkb_state.state, > - seat->xkb_info.caps_led)) > + seat->xkb_info->caps_led)) > leds |= LED_CAPS_LOCK; > if (xkb_state_led_index_is_active(seat->xkb_state.state, > - seat->xkb_info.scroll_led)) > + seat->xkb_info->scroll_led)) > leds |= LED_SCROLL_LOCK; > if (leds != seat->xkb_state.leds && seat->led_update) > seat->led_update(seat, leds); > @@ -1243,8 +1243,8 @@ seat_get_keyboard(struct wl_client *client, struct > wl_resource *resource, > > if (seat->compositor->use_xkbcommon) { > wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, > - seat->xkb_info.keymap_fd, > - seat->xkb_info.keymap_size); > + seat->xkb_info->keymap_fd, > + seat->xkb_info->keymap_size); > } else { > int null_fd = open("/dev/null", O_RDONLY); > wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP, > @@ -1351,8 +1351,12 @@ weston_compositor_xkb_init(struct weston_compositor > *ec, > return 0; > } > > -static void xkb_info_destroy(struct weston_xkb_info *xkb_info) > +static void > +weston_xkb_info_destroy(struct weston_xkb_info
Re: [PATCH weston v2] Copying xkb_info when creating a seat causes problems
On Thu, Sep 05, 2013 at 01:31:40PM +, Andrew Wedgbury wrote: > Hi Kristian, > > Here's a new patch for ref counting weston_xkb_info, as suggested. > So a seat created with a NULL keymap will now point to the global xkb_info. Andrew, that looks great. It's a nice cleanup in itself and of course fixes the premature munmap error. Thanks, applied. Kristian > --- > src/compositor.h |5 ++-- > src/input.c| 77 > > src/text-backend.c |4 +-- > 3 files changed, 53 insertions(+), 33 deletions(-) > > diff --git a/src/compositor.h b/src/compositor.h > index 6db3c61..3755650 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -398,6 +398,7 @@ struct weston_xkb_info { > int keymap_fd; > size_t keymap_size; > char *keymap_area; > + int32_t ref_count; > xkb_mod_index_t shift_mod; > xkb_mod_index_t caps_mod; > xkb_mod_index_t ctrl_mod; > @@ -468,7 +469,7 @@ struct weston_seat { > > void (*led_update)(struct weston_seat *ws, enum weston_led leds); > > - struct weston_xkb_info xkb_info; > + struct weston_xkb_info *xkb_info; > struct { > struct xkb_state *state; > enum weston_led leds; > @@ -588,7 +589,7 @@ struct weston_compositor { > > struct xkb_rule_names xkb_names; > struct xkb_context *xkb_context; > - struct weston_xkb_info xkb_info; > + struct weston_xkb_info *xkb_info; > > /* Raw keyboard processing (no libxkbcommon initialization or handling) > */ > int use_xkbcommon; > diff --git a/src/input.c b/src/input.c > index aa40b4e..78b6ead 100644 > --- a/src/input.c > +++ b/src/input.c > @@ -760,24 +760,24 @@ notify_modifiers(struct weston_seat *seat, uint32_t > serial) > /* And update the modifier_state for bindings. */ > mods_lookup = mods_depressed | mods_latched; > seat->modifier_state = 0; > - if (mods_lookup & (1 << seat->xkb_info.ctrl_mod)) > + if (mods_lookup & (1 << seat->xkb_info->ctrl_mod)) > seat->modifier_state |= MODIFIER_CTRL; > - if (mods_lookup & (1 << seat->xkb_info.alt_mod)) > + if (mods_lookup & (1 << seat->xkb_info->alt_mod)) > seat->modifier_state |= MODIFIER_ALT; > - if (mods_lookup & (1 << seat->xkb_info.super_mod)) > + if (mods_lookup & (1 << seat->xkb_info->super_mod)) > seat->modifier_state |= MODIFIER_SUPER; > - if (mods_lookup & (1 << seat->xkb_info.shift_mod)) > + if (mods_lookup & (1 << seat->xkb_info->shift_mod)) > seat->modifier_state |= MODIFIER_SHIFT; > > /* Finally, notify the compositor that LEDs have changed. */ > if (xkb_state_led_index_is_active(seat->xkb_state.state, > - seat->xkb_info.num_led)) > + seat->xkb_info->num_led)) > leds |= LED_NUM_LOCK; > if (xkb_state_led_index_is_active(seat->xkb_state.state, > - seat->xkb_info.caps_led)) > + seat->xkb_info->caps_led)) > leds |= LED_CAPS_LOCK; > if (xkb_state_led_index_is_active(seat->xkb_state.state, > - seat->xkb_info.scroll_led)) > + seat->xkb_info->scroll_led)) > leds |= LED_SCROLL_LOCK; > if (leds != seat->xkb_state.leds && seat->led_update) > seat->led_update(seat, leds); > @@ -1243,8 +1243,8 @@ seat_get_keyboard(struct wl_client *client, struct > wl_resource *resource, > > if (seat->compositor->use_xkbcommon) { > wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, > - seat->xkb_info.keymap_fd, > - seat->xkb_info.keymap_size); > + seat->xkb_info->keymap_fd, > + seat->xkb_info->keymap_size); > } else { > int null_fd = open("/dev/null", O_RDONLY); > wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP, > @@ -1351,8 +1351,12 @@ weston_compositor_xkb_init(struct weston_compositor > *ec, > return 0; > } > > -static void xkb_info_destroy(struct weston_xkb_info *xkb_info) > +static void > +weston_xkb_info_destroy(struct weston_xkb_info *xkb_info) > { > + if (--xkb_info->ref_count > 0) > + return; > + > if (xkb_info->keymap) > xkb_map_unref(xkb_info->keymap); > > @@ -1360,6 +1364,7 @@ static void xkb_info_destroy(struct weston_xkb_info > *xkb_info) > munmap(xkb_info->keymap_area, xkb_info->keymap_size); > if (xkb_info->keymap_fd >= 0) > close(xkb_info->keymap_fd); > + free(xkb_info); > } > > void > @@ -1377,14 +1382,22 @@ weston_compositor_xkb_destroy(struct > weston_compositor *ec) >
[PATCH weston v3] Copying xkb_info when creating a seat causes problems
Sorry, I missed updating use of xkb_info in compositor-x11.c. I've updated the patch. --- src/compositor-x11.c |2 +- src/compositor.h |5 ++-- src/input.c | 77 +++--- src/text-backend.c |4 +-- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/compositor-x11.c b/src/compositor-x11.c index a896612..e04ea06 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -160,7 +160,7 @@ x11_compositor_get_keymap(struct x11_compositor *c) static uint32_t get_xkb_mod_mask(struct x11_compositor *c, uint32_t in) { - struct weston_xkb_info *info = &c->core_seat.xkb_info; + struct weston_xkb_info *info = c->core_seat.xkb_info; uint32_t ret = 0; if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID) diff --git a/src/compositor.h b/src/compositor.h index 6db3c61..3755650 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -398,6 +398,7 @@ struct weston_xkb_info { int keymap_fd; size_t keymap_size; char *keymap_area; + int32_t ref_count; xkb_mod_index_t shift_mod; xkb_mod_index_t caps_mod; xkb_mod_index_t ctrl_mod; @@ -468,7 +469,7 @@ struct weston_seat { void (*led_update)(struct weston_seat *ws, enum weston_led leds); - struct weston_xkb_info xkb_info; + struct weston_xkb_info *xkb_info; struct { struct xkb_state *state; enum weston_led leds; @@ -588,7 +589,7 @@ struct weston_compositor { struct xkb_rule_names xkb_names; struct xkb_context *xkb_context; - struct weston_xkb_info xkb_info; + struct weston_xkb_info *xkb_info; /* Raw keyboard processing (no libxkbcommon initialization or handling) */ int use_xkbcommon; diff --git a/src/input.c b/src/input.c index aa40b4e..78b6ead 100644 --- a/src/input.c +++ b/src/input.c @@ -760,24 +760,24 @@ notify_modifiers(struct weston_seat *seat, uint32_t serial) /* And update the modifier_state for bindings. */ mods_lookup = mods_depressed | mods_latched; seat->modifier_state = 0; - if (mods_lookup & (1 << seat->xkb_info.ctrl_mod)) + if (mods_lookup & (1 << seat->xkb_info->ctrl_mod)) seat->modifier_state |= MODIFIER_CTRL; - if (mods_lookup & (1 << seat->xkb_info.alt_mod)) + if (mods_lookup & (1 << seat->xkb_info->alt_mod)) seat->modifier_state |= MODIFIER_ALT; - if (mods_lookup & (1 << seat->xkb_info.super_mod)) + if (mods_lookup & (1 << seat->xkb_info->super_mod)) seat->modifier_state |= MODIFIER_SUPER; - if (mods_lookup & (1 << seat->xkb_info.shift_mod)) + if (mods_lookup & (1 << seat->xkb_info->shift_mod)) seat->modifier_state |= MODIFIER_SHIFT; /* Finally, notify the compositor that LEDs have changed. */ if (xkb_state_led_index_is_active(seat->xkb_state.state, - seat->xkb_info.num_led)) + seat->xkb_info->num_led)) leds |= LED_NUM_LOCK; if (xkb_state_led_index_is_active(seat->xkb_state.state, - seat->xkb_info.caps_led)) + seat->xkb_info->caps_led)) leds |= LED_CAPS_LOCK; if (xkb_state_led_index_is_active(seat->xkb_state.state, - seat->xkb_info.scroll_led)) + seat->xkb_info->scroll_led)) leds |= LED_SCROLL_LOCK; if (leds != seat->xkb_state.leds && seat->led_update) seat->led_update(seat, leds); @@ -1243,8 +1243,8 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource, if (seat->compositor->use_xkbcommon) { wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - seat->xkb_info.keymap_fd, - seat->xkb_info.keymap_size); + seat->xkb_info->keymap_fd, + seat->xkb_info->keymap_size); } else { int null_fd = open("/dev/null", O_RDONLY); wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP, @@ -1351,8 +1351,12 @@ weston_compositor_xkb_init(struct weston_compositor *ec, return 0; } -static void xkb_info_destroy(struct weston_xkb_info *xkb_info) +static void +weston_xkb_info_destroy(struct weston_xkb_info *xkb_info) { + if (--xkb_info->ref_count > 0) + return; + if (xkb_info->keymap) xkb_map_unref(xkb_info->keymap); @@ -1360,6 +1364,7 @@ static void xkb_info_destroy(struct weston_xkb_info *xkb_info) munmap(xkb_info->keymap_area, xkb_info->keymap_size); if (xkb_info->keymap_fd >=
[PATCH weston v2] Copying xkb_info when creating a seat causes problems
Hi Kristian, Here's a new patch for ref counting weston_xkb_info, as suggested. So a seat created with a NULL keymap will now point to the global xkb_info. --- src/compositor.h |5 ++-- src/input.c| 77 src/text-backend.c |4 +-- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/compositor.h b/src/compositor.h index 6db3c61..3755650 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -398,6 +398,7 @@ struct weston_xkb_info { int keymap_fd; size_t keymap_size; char *keymap_area; + int32_t ref_count; xkb_mod_index_t shift_mod; xkb_mod_index_t caps_mod; xkb_mod_index_t ctrl_mod; @@ -468,7 +469,7 @@ struct weston_seat { void (*led_update)(struct weston_seat *ws, enum weston_led leds); - struct weston_xkb_info xkb_info; + struct weston_xkb_info *xkb_info; struct { struct xkb_state *state; enum weston_led leds; @@ -588,7 +589,7 @@ struct weston_compositor { struct xkb_rule_names xkb_names; struct xkb_context *xkb_context; - struct weston_xkb_info xkb_info; + struct weston_xkb_info *xkb_info; /* Raw keyboard processing (no libxkbcommon initialization or handling) */ int use_xkbcommon; diff --git a/src/input.c b/src/input.c index aa40b4e..78b6ead 100644 --- a/src/input.c +++ b/src/input.c @@ -760,24 +760,24 @@ notify_modifiers(struct weston_seat *seat, uint32_t serial) /* And update the modifier_state for bindings. */ mods_lookup = mods_depressed | mods_latched; seat->modifier_state = 0; - if (mods_lookup & (1 << seat->xkb_info.ctrl_mod)) + if (mods_lookup & (1 << seat->xkb_info->ctrl_mod)) seat->modifier_state |= MODIFIER_CTRL; - if (mods_lookup & (1 << seat->xkb_info.alt_mod)) + if (mods_lookup & (1 << seat->xkb_info->alt_mod)) seat->modifier_state |= MODIFIER_ALT; - if (mods_lookup & (1 << seat->xkb_info.super_mod)) + if (mods_lookup & (1 << seat->xkb_info->super_mod)) seat->modifier_state |= MODIFIER_SUPER; - if (mods_lookup & (1 << seat->xkb_info.shift_mod)) + if (mods_lookup & (1 << seat->xkb_info->shift_mod)) seat->modifier_state |= MODIFIER_SHIFT; /* Finally, notify the compositor that LEDs have changed. */ if (xkb_state_led_index_is_active(seat->xkb_state.state, - seat->xkb_info.num_led)) + seat->xkb_info->num_led)) leds |= LED_NUM_LOCK; if (xkb_state_led_index_is_active(seat->xkb_state.state, - seat->xkb_info.caps_led)) + seat->xkb_info->caps_led)) leds |= LED_CAPS_LOCK; if (xkb_state_led_index_is_active(seat->xkb_state.state, - seat->xkb_info.scroll_led)) + seat->xkb_info->scroll_led)) leds |= LED_SCROLL_LOCK; if (leds != seat->xkb_state.leds && seat->led_update) seat->led_update(seat, leds); @@ -1243,8 +1243,8 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource, if (seat->compositor->use_xkbcommon) { wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - seat->xkb_info.keymap_fd, - seat->xkb_info.keymap_size); + seat->xkb_info->keymap_fd, + seat->xkb_info->keymap_size); } else { int null_fd = open("/dev/null", O_RDONLY); wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP, @@ -1351,8 +1351,12 @@ weston_compositor_xkb_init(struct weston_compositor *ec, return 0; } -static void xkb_info_destroy(struct weston_xkb_info *xkb_info) +static void +weston_xkb_info_destroy(struct weston_xkb_info *xkb_info) { + if (--xkb_info->ref_count > 0) + return; + if (xkb_info->keymap) xkb_map_unref(xkb_info->keymap); @@ -1360,6 +1364,7 @@ static void xkb_info_destroy(struct weston_xkb_info *xkb_info) munmap(xkb_info->keymap_area, xkb_info->keymap_size); if (xkb_info->keymap_fd >= 0) close(xkb_info->keymap_fd); + free(xkb_info); } void @@ -1377,14 +1382,22 @@ weston_compositor_xkb_destroy(struct weston_compositor *ec) free((char *) ec->xkb_names.layout); free((char *) ec->xkb_names.variant); free((char *) ec->xkb_names.options); - - xkb_info_destroy(&ec->xkb_info); + + if (ec->xkb_info) + weston_xkb_info_destroy(ec->xkb_info); xkb_context_unref(ec->xkb_conte
Re: [PATCH weston] Copying xkb_info when creating a seat causes problems
On Wed, Sep 4, 2013 at 5:49 AM, Andrew Wedgbury wrote: > A simpler fix would be to not call xkb_info_destroy() when releasing a seat > in the case where the xkb_info for the seat was copied from the global > compositor settings (which can be determined by checking if keymap_fd is the > same) > > In this case, xkb_map_unref() should still be called to unref the keymap. > > This appears to fix things for me, so I can now create and destroy many seats. Nice, the fix looks right. I think the underlying problem is that the way we share and create xkb_info is a little odd and I think we'd be better off ref-counting the structure. In weston_seat_init_keyboard, we'd then do if (keymap != NULL) { seat->xkb_info = weston_xkb_info_create(keymap); } else { seat->xkb_info = seat->compositor->xkb_info; seat->xkb_info->ref_count++; } and then rename xkb_info_destroy to weston_xkb_info_destroy() and make it decrement ref_count and return immediately if it's > 0. Kristian > --- > src/input.c |7 ++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/src/input.c b/src/input.c > index 325a48f..d99798e 100644 > --- a/src/input.c > +++ b/src/input.c > @@ -1600,7 +1600,12 @@ weston_seat_release(struct weston_seat *seat) > if (seat->compositor->use_xkbcommon) { > if (seat->xkb_state.state != NULL) > xkb_state_unref(seat->xkb_state.state); > - xkb_info_destroy(&seat->xkb_info); > + > + if (seat->xkb_info.keymap_fd != > + seat->compositor->xkb_info.keymap_fd) > + xkb_info_destroy(&seat->xkb_info); > + else if (seat->xkb_info.keymap) > + xkb_map_unref(seat->xkb_info.keymap); > } > #endif > > -- > 1.7.10.4 > ___ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] Copying xkb_info when creating a seat causes problems
A simpler fix would be to not call xkb_info_destroy() when releasing a seat in the case where the xkb_info for the seat was copied from the global compositor settings (which can be determined by checking if keymap_fd is the same) In this case, xkb_map_unref() should still be called to unref the keymap. This appears to fix things for me, so I can now create and destroy many seats. --- src/input.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/input.c b/src/input.c index 325a48f..d99798e 100644 --- a/src/input.c +++ b/src/input.c @@ -1600,7 +1600,12 @@ weston_seat_release(struct weston_seat *seat) if (seat->compositor->use_xkbcommon) { if (seat->xkb_state.state != NULL) xkb_state_unref(seat->xkb_state.state); - xkb_info_destroy(&seat->xkb_info); + + if (seat->xkb_info.keymap_fd != + seat->compositor->xkb_info.keymap_fd) + xkb_info_destroy(&seat->xkb_info); + else if (seat->xkb_info.keymap) + xkb_map_unref(seat->xkb_info.keymap); } #endif -- 1.7.10.4 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Copying xkb_info when creating a seat causes problems
Hi, I noticed that when creating a seat, calling weston_seat_init_keyboard() with a NULL keymap argument copies the global xkb_info struct from the compositor. This causes a problem if you then delete the seat, since the code in xkb_info_destroy() munmaps keymap_area and closes keymap_fd (the same pointer and fd as the global xkb_info). At this point keyboard input stops working, and trying to create another seat causes weston to crash. Not entirely sure what the best solution is. Perhaps it should reference the global compositor settings somehow, rather than copy the struct? --- Andrew Wedgbury ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel