Re: [PATCH] Destroy resources when destroying input and output

2014-05-14 Thread Neil Roberts
After looking at it a bit more I don't think we can really make the
automatic zombie idea work. The trouble is that libwayland-server would
need to know when the client has destroyed the proxy in order to destroy
the zombie resource. However the destroy semantics are
interface-dependent so only an implementation of the interface can know
when the resource is really destroyed.

The wl_output interface doesn't currently have a destructor so in this
particular case it's even worse. I guess if a client binds to an output
then the resource for it has to leak until the client disconnects.

Assuming we later add a release request to wl_output (I think we should)
then I think we would still need to make the zombie handling specific to
the output implementation in Weston. We can't just set the
implementation to NULL because then nothing would destroy the resource
when the release request is called.

Perhaps the best thing to do would be to make Weston swap out the
interface for a simple one that only waits for the release event when an
output is unplugged. We would also have to do this for pointers,
keyboards and touch devices. This could end up with quite a lot of code
because you have to double up all of the implementations. We also have
to be aware of these zombie objects if we ever add any more requests
that can refer to these objects because they would have to check if the
object is a zombie and skip the request.

If there's ever a Wayland 2.0 I think it would be good to make all
interfaces implicitly have a destructor which is handled outside of the
protocol description. I can't think of an interface that shouldn't have
a destructor. Even with wl_callback which is defined to be destroyed
when it is signalled it might make sense to allow the client to destroy
the callback early if it's no longer interested.

Regards,
- Neil
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-14 Thread Pekka Paalanen
On Wed, 14 May 2014 19:12:20 +0100
Neil Roberts n...@linux.intel.com wrote:

 After looking at it a bit more I don't think we can really make
 the automatic zombie idea work. The trouble is that
 libwayland-server would need to know when the client has
 destroyed the proxy in order to destroy the zombie resource.
 However the destroy semantics are interface-dependent so only an
 implementation of the interface can know when the resource is
 really destroyed.
 
 The wl_output interface doesn't currently have a destructor so in
 this particular case it's even worse. I guess if a client binds
 to an output then the resource for it has to leak until the
 client disconnects.
 
 Assuming we later add a release request to wl_output (I think we
 should) then I think we would still need to make the zombie
 handling specific to the output implementation in Weston. We
 can't just set the implementation to NULL because then nothing
 would destroy the resource when the release request is called.

I think you are totally right.

 Perhaps the best thing to do would be to make Weston swap out the
 interface for a simple one that only waits for the release event
 when an output is unplugged. We would also have to do this for
 pointers, keyboards and touch devices. This could end up with
 quite a lot of code because you have to double up all of the
 implementations. We also have to be aware of these zombie objects
 if we ever add any more requests that can refer to these objects
 because they would have to check if the object is a zombie and
 skip the request.

Right.

 If there's ever a Wayland 2.0 I think it would be good to make all
 interfaces implicitly have a destructor which is handled outside
 of the protocol description. I can't think of an interface that
 shouldn't have a destructor. Even with wl_callback which is
 defined to be destroyed when it is signalled it might make sense
 to allow the client to destroy the callback early if it's no
 longer interested.

Yeah, I think there are ways to make it work, if we could change
it. Another idea would be to annotate destructors and allow both
requests and events to be destructors.

I think I have suggested this before, but we could start collecting
a Wayland protocol extension designer's cook book: rules of thumb
(e.g. always define destructor protocol unless it is explicitly not
right), design patterns (inert objects, factory interfaces...),
where and how to define errors etc.


Thanks,
pq
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-09 Thread Pekka Paalanen
On Thu, 8 May 2014 19:32:12 -0500
Jason Ekstrand ja...@jlekstrand.net wrote:

 On Tue, Dec 31, 2013 at 3:37 AM, Pekka Paalanen ppaala...@gmail.com wrote:
 
  You cannot just go and destroy wl_resources, because there are
  clients using them - that is why the wl_resources exist in the
  first place. Clients use all protocol objects they have, and if the
  protocol does not say an object is destroyed, then it must be legal
  to use it, regardless of what happens in the server.
 
  If you can guarantee, that clients know the protocol object has
  gone away without any races, then the clients have already
  destroyed the protocol objects themselves, which means that you
  have no wl_resources to destroy in the list.
 
  If you cannot guarantee that, then the protocol objects
  (wl_resources) must continue to exist in such a way, that clients
  do not get a fatal protocol error when using them. The objects just
  do nothing. This state is called inert.
 
  If this principle is broken, it usually leads to races between the
  server and the client, which sometimes leads to a fatal protocol
  error and causes disconnection of the client. This happens, when the
  server destroys a wl_resource, and then receives a request from the
  client for that destroyed resource. The client may have sent the
  request even before the wl_resource was destroyed in the server, at
  which point it was a legal request from the client's perspective
  (this is the essence of the race).
 
  However, since wl_output interface contains no requests, your patch
  might be right. A client cannot send a wl_output request after the
  wl_resource has been destroyed in the server, because the interface
  has no requests.
 
  The wl_output could still be used as an argument to other requests
  in other interfaces, though. Whether that is fatal, or just
  silently gets turned into NULL argument in libwayland-server, I do
  not remember off-hand. Would be best to verify what happens in that
  case, since it must not be fatal to the client.
 
 
 Yes, I just looked it up.  If a client sends a request with the output as
 an argument after the output gets destroyed, the client will get an
 INVALID_OBJECT protocol error and disconnect.  This is a problem.
 
 
 
  If this patch leads to a race with possibly a protocol error as the
  result (think about output hot-unplug), then I think you would need
  to turn the wl_resource into an inert object instead of destroying
  it directly.
 
 
 The way to do this would be to set dummy handler and call
 wl_resource_set_destructor(resource, NULL);  This leaves the resource inert
 and allows us to destroy the underlying object.  The resources will get
 cleaned up when the client quits.

Looking at it in general, there is one more fun complication.

If the inert object has requests in its interface, that create new
objects, the server cannot just ignore those requests. I think the
server will need to actually create new objects if requested, but
make those inert too. Otherwise there would again be a mismatch
between the server and the client on which objects exist.


Thanks,
pq
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-09 Thread Neil Roberts
Perhaps we should consider applying the patch anyway even though it's
not ideal. Currently if a client uses a dead output in a request such as
xdg_surface.set_output Weston will end up with a weston_output pointer
that points to freed memory. This could cause the compositor to crash.
That is worse than the alternative provided by this patch which is to
make the client abort. The clients know about the output being destroyed
via the wl_registry.global_remove event so in practice they would only
hit the problem in the unlikely event that they used the output in a
request in the short time between the output being unplugged and
noticing the removal event.

In the longer term I was thinking maybe it would be good to handle the
inert resource idea within libwayland-server. We could add a function
like wl_resource_zombify() which would mark the resource as a zombie and
call the destroy handlers. From the compositor's perspective it can then
act as if the resource has been destroyed. We could detect zombie
resources being used within the request marshalling code and ignore the
request. If the request creates new resource we can internally create
new zombie resources too and Weston would never need to know about it. I
am planning to experiment with this approach now.

Regards,
- Neil
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-09 Thread Pekka Paalanen
On Fri, 09 May 2014 14:33:58 +0100
Neil Roberts n...@linux.intel.com wrote:

 Perhaps we should consider applying the patch anyway even though it's
 not ideal. Currently if a client uses a dead output in a request such as
 xdg_surface.set_output Weston will end up with a weston_output pointer
 that points to freed memory. This could cause the compositor to crash.

True, it's very bad now.

 That is worse than the alternative provided by this patch which is to
 make the client abort. The clients know about the output being destroyed
 via the wl_registry.global_remove event so in practice they would only
 hit the problem in the unlikely event that they used the output in a
 request in the short time between the output being unplugged and
 noticing the removal event.

That is also true, but if it is fixed improperly now, there is a very
good chance we just forget about the problem, and never fix it for
real. Especially when it becomes very hard to trigger.

At least make sure we have an open bug report about it, please.

 In the longer term I was thinking maybe it would be good to handle the
 inert resource idea within libwayland-server. We could add a function
 like wl_resource_zombify() which would mark the resource as a zombie and
 call the destroy handlers. From the compositor's perspective it can then
 act as if the resource has been destroyed. We could detect zombie
 resources being used within the request marshalling code and ignore the
 request. If the request creates new resource we can internally create
 new zombie resources too and Weston would never need to know about it. I
 am planning to experiment with this approach now.

Hmm... will be interesting to see, if that works out. It does feel like
quite a lot of magic in libwayland-server, while also making life a lot
easier.


Thanks,
pq
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-09 Thread Jason Ekstrand
On Fri, May 9, 2014 at 1:37 AM, Pekka Paalanen ppaala...@gmail.com wrote:
 Looking at it in general, there is one more fun complication.

 If the inert object has requests in its interface, that create new
 objects, the server cannot just ignore those requests. I think the
 server will need to actually create new objects if requested, but
 make those inert too. Otherwise there would again be a mismatch
 between the server and the client on which objects exist.

I was hoping that this wasn't actually going to be a problem, but on
wl_seat it is.  The server can destroy a seat while a client is calling
wl_seat.get_pointer for instance.  Then, yes, we do have to create an
intert object.

On Fri, May 9, 2014 at 9:02 AM, Pekka Paalanen ppaala...@gmail.com wrote:

 On Fri, 09 May 2014 14:33:58 +0100
 Neil Roberts n...@linux.intel.com wrote:

  Perhaps we should consider applying the patch anyway even though it's
  not ideal. Currently if a client uses a dead output in a request such as
  xdg_surface.set_output Weston will end up with a weston_output pointer
  that points to freed memory. This could cause the compositor to crash.

 True, it's very bad now.

  That is worse than the alternative provided by this patch which is to
  make the client abort. The clients know about the output being destroyed
  via the wl_registry.global_remove event so in practice they would only
  hit the problem in the unlikely event that they used the output in a
  request in the short time between the output being unplugged and
  noticing the removal event.

 That is also true, but if it is fixed improperly now, there is a very
 good chance we just forget about the problem, and never fix it for
 real. Especially when it becomes very hard to trigger.

 At least make sure we have an open bug report about it, please.


I agree.  This is bad and we need to make sure it gets fixed properly.



  In the longer term I was thinking maybe it would be good to handle the
  inert resource idea within libwayland-server. We could add a function
  like wl_resource_zombify() which would mark the resource as a zombie and
  call the destroy handlers. From the compositor's perspective it can then
  act as if the resource has been destroyed. We could detect zombie
  resources being used within the request marshalling code and ignore the
  request. If the request creates new resource we can internally create
  new zombie resources too and Weston would never need to know about it. I
  am planning to experiment with this approach now.

 Hmm... will be interesting to see, if that works out. It does feel like
 quite a lot of magic in libwayland-server, while also making life a lot
 easier.


Most of the magic there is in allowing resources with no handler in
libwayland-server.  The patch would be about 4 lines.  Right now,
client-side wl_proxy objects are allowed to have a NULL implementation and
there's no problem;  server-side, this is not currently allowed.  If we
allowed this ten Neil's wl_resource_zombify would only have to set the
destructor, and implementation to NULL.  For that matter, we could just do
that explicitly in weston and not add API for it.

The big chunk of magic is in handling new_id requests.  We would need to
create zombie wl_resource's for each new_id argument on a call to a
zombified wl_resource.  Now that Pekka mentioned it, I'm not sure that
we're handling those correctly client-side if there's no implementation set.

--Jason Ekstrand
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-09 Thread Neil Roberts
Jason Ekstrand ja...@jlekstrand.net writes:

 Most of the magic there is in allowing resources with no handler in
 libwayland-server. The patch would be about 4 lines. Right now,
 client-side wl_proxy objects are allowed to have a NULL implementation
 and there's no problem; server-side, this is not currently allowed. If
 we allowed this ten Neil's wl_resource_zombify would only have to set
 the destructor, and implementation to NULL. For that matter, we could
 just do that explicitly in weston and not add API for it.

Don't forget that we also want to ignore requests that have zombie
resources as arguments, not just if the resource is directly used as a
target of a request.

It looks like the client-side already has code to handle zombie objects
by putting a marker called WL_ZOMBIE_OBJECT in the ID map. Perhaps we
should use the same mechanism on the server side too.

If a zombie object is received in an event on the client side it looks
like wl_closure_lookup_objects just sets the proxy object to NULL. Is
that safe? Wouldn't the event handlers crash if they get a NULL resource
in an event?

If we can somehow make wl_closure_lookup_objects report when it finds a
zombie object we can make the upper layers just consume the event. We
could do this on both the client and side and the server side.

- Neil
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] Destroy resources when destroying input and output

2014-05-08 Thread Jason Ekstrand
On Tue, Dec 31, 2013 at 3:37 AM, Pekka Paalanen ppaala...@gmail.com wrote:

 On Wed, 25 Dec 2013 17:02:09 +0100
 Mariusz Ceier mceier+wayl...@gmail.com wrote:

  Some structures containing resources list are freed before
  resources on that list are destroyed, and that triggers invalid
  read/write in compositor.c:3103 indirectly called from
  text-backend.c:938 when running weston under valgrind.
 
  This patch destroys resources on these lists before such
  structures are freed.
 
  That fixes at least x11 and freerds backend.
 
  Signed-off-by: Mariusz Ceier mceier+wayl...@gmail.com
  ---
   src/compositor.c |  4 
   src/input.c  | 15 ---
   2 files changed, 16 insertions(+), 3 deletions(-)
 
  diff --git a/src/compositor.c b/src/compositor.c
  index ff0f3ab..a4077e8 100644
  --- a/src/compositor.c
  +++ b/src/compositor.c
  @@ -3183,6 +3183,7 @@ weston_compositor_verify_pointers(struct
  weston_compositor *ec) WL_EXPORT void
   weston_output_destroy(struct weston_output *output)
   {
  + struct wl_resource *resource, *next_resource;
output-destroying = 1;
 
weston_compositor_remove_output(output-compositor,
  output); @@ -3192,6 +3193,9 @@ weston_output_destroy(struct
  weston_output *output)
wl_signal_emit(output-destroy_signal, output);
 
  + wl_resource_for_each_safe(resource, next_resource,
  output-resource_list)
  + wl_resource_destroy(resource);
  +

 Hi,

 I didn't check the other cases, but this case seems suspicious at
 first. There is the following fundamental principle with Wayland
 protocol objects as I understand it.

 You cannot just go and destroy wl_resources, because there are
 clients using them - that is why the wl_resources exist in the
 first place. Clients use all protocol objects they have, and if the
 protocol does not say an object is destroyed, then it must be legal
 to use it, regardless of what happens in the server.

 If you can guarantee, that clients know the protocol object has
 gone away without any races, then the clients have already
 destroyed the protocol objects themselves, which means that you
 have no wl_resources to destroy in the list.

 If you cannot guarantee that, then the protocol objects
 (wl_resources) must continue to exist in such a way, that clients
 do not get a fatal protocol error when using them. The objects just
 do nothing. This state is called inert.

 If this principle is broken, it usually leads to races between the
 server and the client, which sometimes leads to a fatal protocol
 error and causes disconnection of the client. This happens, when the
 server destroys a wl_resource, and then receives a request from the
 client for that destroyed resource. The client may have sent the
 request even before the wl_resource was destroyed in the server, at
 which point it was a legal request from the client's perspective
 (this is the essence of the race).

 However, since wl_output interface contains no requests, your patch
 might be right. A client cannot send a wl_output request after the
 wl_resource has been destroyed in the server, because the interface
 has no requests.

 The wl_output could still be used as an argument to other requests
 in other interfaces, though. Whether that is fatal, or just
 silently gets turned into NULL argument in libwayland-server, I do
 not remember off-hand. Would be best to verify what happens in that
 case, since it must not be fatal to the client.


Yes, I just looked it up.  If a client sends a request with the output as
an argument after the output gets destroyed, the client will get an
INVALID_OBJECT protocol error and disconnect.  This is a problem.



 If this patch leads to a race with possibly a protocol error as the
 result (think about output hot-unplug), then I think you would need
 to turn the wl_resource into an inert object instead of destroying
 it directly.


The way to do this would be to set dummy handler and call
wl_resource_set_destructor(resource, NULL);  This leaves the resource inert
and allows us to destroy the underlying object.  The resources will get
cleaned up when the client quits.  The reason for the invalid read/write is
because the resource destructor calls wl_list_remove on the resource's
internal wl_list link.  Because we deleted the underlying weston_output
object, this results in an invalid read/write.



 The same idea applies to the hunks below, too.


 Thanks,
 pq

free(output-name);
pixman_region32_fini(output-region);
pixman_region32_fini(output-previous_damage);
  diff --git a/src/input.c b/src/input.c
  index 07e9d6c..062a2cb 100644
  --- a/src/input.c
  +++ b/src/input.c
  @@ -471,10 +471,13 @@ weston_pointer_create(struct weston_seat
  *seat) WL_EXPORT void
   weston_pointer_destroy(struct weston_pointer *pointer)
   {
  + struct wl_resource *resource, *next_resource;
  +
if (pointer-sprite)
pointer_unmap_sprite(pointer);
 
  - /* XXX: What about 

[PATCH] Destroy resources when destroying input and output

2013-12-25 Thread Mariusz Ceier
Some structures containing resources list are freed before resources
on that list are destroyed, and that triggers invalid read/write
in compositor.c:3103 indirectly called from text-backend.c:938
when running weston under valgrind.

This patch destroys resources on these lists before such
structures are freed.

That fixes at least x11 and freerds backend.

Signed-off-by: Mariusz Ceier mceier+wayl...@gmail.com
---
 src/compositor.c |  4 
 src/input.c  | 15 ---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index ff0f3ab..a4077e8 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3183,6 +3183,7 @@ weston_compositor_verify_pointers(struct 
weston_compositor *ec)
 WL_EXPORT void
 weston_output_destroy(struct weston_output *output)
 {
+   struct wl_resource *resource, *next_resource;
output-destroying = 1;
 
weston_compositor_remove_output(output-compositor, output);
@@ -3192,6 +3193,9 @@ weston_output_destroy(struct weston_output *output)
 
wl_signal_emit(output-destroy_signal, output);
 
+   wl_resource_for_each_safe(resource, next_resource, 
output-resource_list)
+   wl_resource_destroy(resource);
+
free(output-name);
pixman_region32_fini(output-region);
pixman_region32_fini(output-previous_damage);
diff --git a/src/input.c b/src/input.c
index 07e9d6c..062a2cb 100644
--- a/src/input.c
+++ b/src/input.c
@@ -471,10 +471,13 @@ weston_pointer_create(struct weston_seat *seat)
 WL_EXPORT void
 weston_pointer_destroy(struct weston_pointer *pointer)
 {
+   struct wl_resource *resource, *next_resource;
+
if (pointer-sprite)
pointer_unmap_sprite(pointer);
 
-   /* XXX: What about pointer-resource_list? */
+   wl_resource_for_each_safe(resource, next_resource, 
pointer-resource_list)
+   wl_resource_destroy(resource);
 
wl_list_remove(pointer-focus_resource_listener.link);
wl_list_remove(pointer-focus_view_listener.link);
@@ -520,7 +523,7 @@ weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
 WL_EXPORT void
 weston_keyboard_destroy(struct weston_keyboard *keyboard)
 {
-   /* XXX: What about keyboard-resource_list? */
+   struct wl_resource *resource, *next_resource;
 
 #ifdef ENABLE_XKBCOMMON
if (keyboard-seat-compositor-use_xkbcommon) {
@@ -533,6 +536,9 @@ weston_keyboard_destroy(struct weston_keyboard *keyboard)
}
 #endif
 
+   wl_resource_for_each_safe(resource, next_resource, 
keyboard-resource_list)
+   wl_resource_destroy(resource);
+
wl_array_release(keyboard-keys);
wl_list_remove(keyboard-focus_resource_listener.link);
free(keyboard);
@@ -570,7 +576,10 @@ weston_touch_create(void)
 WL_EXPORT void
 weston_touch_destroy(struct weston_touch *touch)
 {
-   /* XXX: What about touch-resource_list? */
+   struct wl_resource *resource, *next_resource;
+
+   wl_resource_for_each_safe(resource, next_resource, 
touch-resource_list)
+   wl_resource_destroy(resource);
 
wl_list_remove(touch-focus_view_listener.link);
wl_list_remove(touch-focus_resource_listener.link);
-- 
1.8.5.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel