fix(core): claim proxies atomically before sending destructors
- commit
- 26d3440eb60a9e7c47e534f875424b8f753ff300
- author
- brice · · 2026-09-28 07:44 UTC
- parent
- 60778dc
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
5 files · +95 -41
M core.go +29 -0
| @@ -89,6 +89,35 @@ func (c *Context) CheckProxy(proxy Proxy) error { | |||
| 89 | 89 | return nil | |
| 90 | 90 | } | |
| 91 | 91 | ||
| 92 | + | // SendDestructor sends a destructor request exactly once. The proxy is | |
| 93 | + | // unregistered atomically before sending, so concurrent callers cannot both | |
| 94 | + | // write it; the losers receive an error and nothing reaches the wire. | |
| 95 | + | func (c *Context) SendDestructor(proxy Proxy, opcode uint32, args ...interface{}) error { | |
| 96 | + | if err := c.claimDestroy(proxy); err != nil { | |
| 97 | + | return err | |
| 98 | + | } | |
| 99 | + | return c.display.SendRequest(proxy.ID(), uint16(opcode), args...) | |
| 100 | + | } | |
| 101 | + | ||
| 102 | + | // SendDestructorWithFDs is SendDestructor for requests carrying FDs. | |
| 103 | + | func (c *Context) SendDestructorWithFDs(proxy Proxy, opcode uint32, fds []int, args ...interface{}) error { | |
| 104 | + | if err := c.claimDestroy(proxy); err != nil { | |
| 105 | + | return err | |
| 106 | + | } | |
| 107 | + | return c.display.SendRequestWithFDs(proxy.ID(), uint16(opcode), fds, args...) | |
| 108 | + | } | |
| 109 | + | ||
| 110 | + | func (c *Context) claimDestroy(proxy Proxy) error { | |
| 111 | + | if err := c.CheckProxy(proxy); err != nil { | |
| 112 | + | return err | |
| 113 | + | } | |
| 114 | + | if !c.proxies.CompareAndDelete(proxy.ID(), proxy) { | |
| 115 | + | return errors.New("proxy is not registered") | |
| 116 | + | } | |
| 117 | + | c.display.objects.CompareAndDelete(proxy.ID(), proxy) | |
| 118 | + | return nil | |
| 119 | + | } | |
| 120 | + | ||
| 92 | 121 | // Register registers a proxy object | |
| 93 | 122 | func (c *Context) Register(proxy Proxy) { | |
| 94 | 123 | if proxy != nil && proxy.ID() != 0 && !c.closed.Load() { | |
| @@ -89,6 +89,35 @@ func (c *Context) CheckProxy(proxy Proxy) error { | |||||
| 89 | return nil | 89 | return nil | ||
| 90 | } | 90 | } | ||
| 91 | 91 | ||||
| 92 | + | // SendDestructor sends a destructor request exactly once. The proxy is | |||
| 93 | + | // unregistered atomically before sending, so concurrent callers cannot both | |||
| 94 | + | // write it; the losers receive an error and nothing reaches the wire. | |||
| 95 | + | func (c *Context) SendDestructor(proxy Proxy, opcode uint32, args ...interface{}) error { | |||
| 96 | + | if err := c.claimDestroy(proxy); err != nil { | |||
| 97 | + | return err | |||
| 98 | + | } | |||
| 99 | + | return c.display.SendRequest(proxy.ID(), uint16(opcode), args...) | |||
| 100 | + | } | |||
| 101 | + | ||||
| 102 | + | // SendDestructorWithFDs is SendDestructor for requests carrying FDs. | |||
| 103 | + | func (c *Context) SendDestructorWithFDs(proxy Proxy, opcode uint32, fds []int, args ...interface{}) error { | |||
| 104 | + | if err := c.claimDestroy(proxy); err != nil { | |||
| 105 | + | return err | |||
| 106 | + | } | |||
| 107 | + | return c.display.SendRequestWithFDs(proxy.ID(), uint16(opcode), fds, args...) | |||
| 108 | + | } | |||
| 109 | + | ||||
| 110 | + | func (c *Context) claimDestroy(proxy Proxy) error { | |||
| 111 | + | if err := c.CheckProxy(proxy); err != nil { | |||
| 112 | + | return err | |||
| 113 | + | } | |||
| 114 | + | if !c.proxies.CompareAndDelete(proxy.ID(), proxy) { | |||
| 115 | + | return errors.New("proxy is not registered") | |||
| 116 | + | } | |||
| 117 | + | c.display.objects.CompareAndDelete(proxy.ID(), proxy) | |||
| 118 | + | return nil | |||
| 119 | + | } | |||
| 120 | + | ||||
| 92 | // Register registers a proxy object | 121 | // Register registers a proxy object | ||
| 93 | func (c *Context) Register(proxy Proxy) { | 122 | func (c *Context) Register(proxy Proxy) { | ||
| 94 | if proxy != nil && proxy.ID() != 0 && !c.closed.Load() { | 123 | if proxy != nil && proxy.ID() != 0 && !c.closed.Load() { | ||
M internal/scanner/scanner.go +8 -2
| @@ -490,11 +490,17 @@ func (s *Scanner) processRequest(iface Interface, req Request, opcode int) (requ | |||
| 490 | 490 | if len(argExprs) > 0 { | |
| 491 | 491 | args = ", " + strings.Join(argExprs, ", ") | |
| 492 | 492 | } | |
| 493 | + | // Destructors claim the proxy atomically before sending so a concurrent | |
| 494 | + | // second destroy cannot reach the wire. | |
| 495 | + | send := "SendRequest" | |
| 496 | + | if data.Destructor { | |
| 497 | + | send = "SendDestructor" | |
| 498 | + | } | |
| 493 | 499 | if len(fdExprs) > 0 { | |
| 494 | 500 | data.HasFDs = true | |
| 495 | - | data.SendCall = fmt.Sprintf("SendRequestWithFDs(o, %d, []int{%s}%s)", opcode, strings.Join(fdExprs, ", "), args) | |
| 501 | + | data.SendCall = fmt.Sprintf("%sWithFDs(o, %d, []int{%s}%s)", send, opcode, strings.Join(fdExprs, ", "), args) | |
| 496 | 502 | } else { | |
| 497 | - | data.SendCall = fmt.Sprintf("SendRequest(o, %d%s)", opcode, args) | |
| 503 | + | data.SendCall = fmt.Sprintf("%s(o, %d%s)", send, opcode, args) | |
| 498 | 504 | } | |
| 499 | 505 | if data.CreatesChild { | |
| 500 | 506 | data.Results = "(*" + data.ChildType + ", error)" | |
| @@ -490,11 +490,17 @@ func (s *Scanner) processRequest(iface Interface, req Request, opcode int) (requ | |||||
| 490 | if len(argExprs) > 0 { | 490 | if len(argExprs) > 0 { | ||
| 491 | args = ", " + strings.Join(argExprs, ", ") | 491 | args = ", " + strings.Join(argExprs, ", ") | ||
| 492 | } | 492 | } | ||
| 493 | + | // Destructors claim the proxy atomically before sending so a concurrent | |||
| 494 | + | // second destroy cannot reach the wire. | |||
| 495 | + | send := "SendRequest" | |||
| 496 | + | if data.Destructor { | |||
| 497 | + | send = "SendDestructor" | |||
| 498 | + | } | |||
| 493 | if len(fdExprs) > 0 { | 499 | if len(fdExprs) > 0 { | ||
| 494 | data.HasFDs = true | 500 | data.HasFDs = true | ||
| 495 | - | data.SendCall = fmt.Sprintf("SendRequestWithFDs(o, %d, []int{%s}%s)", opcode, strings.Join(fdExprs, ", "), args) | 501 | + | data.SendCall = fmt.Sprintf("%sWithFDs(o, %d, []int{%s}%s)", send, opcode, strings.Join(fdExprs, ", "), args) |
| 496 | } else { | 502 | } else { | ||
| 497 | - | data.SendCall = fmt.Sprintf("SendRequest(o, %d%s)", opcode, args) | 503 | + | data.SendCall = fmt.Sprintf("%s(o, %d%s)", send, opcode, args) |
| 498 | } | 504 | } | ||
| 499 | if data.CreatesChild { | 505 | if data.CreatesChild { | ||
| 500 | data.Results = "(*" + data.ChildType + ", error)" | 506 | data.Results = "(*" + data.ChildType + ", error)" | ||
M internal/scanner/template.go +0 -3
| @@ -73,9 +73,6 @@ if err := o.Context().CheckProxy(o); err != nil { return {{.ErrorReturn}} } | |||
| 73 | 73 | {{- range .FDArgs}} | |
| 74 | 74 | _ = wl.CloseSentFD({{.}}) | |
| 75 | 75 | {{- end}} | |
| 76 | - | {{- if .Destructor}} | |
| 77 | - | o.Context().Unregister(o) | |
| 78 | - | {{- end}} | |
| 79 | 76 | {{- if .CreatesChild}} | |
| 80 | 77 | return {{.ChildVar}}, nil | |
| 81 | 78 | {{- else}} | |
| @@ -73,9 +73,6 @@ if err := o.Context().CheckProxy(o); err != nil { return {{.ErrorReturn}} } | |||||
| 73 | {{- range .FDArgs}} | 73 | {{- range .FDArgs}} | ||
| 74 | _ = wl.CloseSentFD({{.}}) | 74 | _ = wl.CloseSentFD({{.}}) | ||
| 75 | {{- end}} | 75 | {{- end}} | ||
| 76 | - | {{- if .Destructor}} | |||
| 77 | - | o.Context().Unregister(o) | |||
| 78 | - | {{- end}} | |||
| 79 | {{- if .CreatesChild}} | 76 | {{- if .CreatesChild}} | ||
| 80 | return {{.ChildVar}}, nil | 77 | return {{.ChildVar}}, nil | ||
| 81 | {{- else}} | 78 | {{- else}} | ||
M protocol/core/core_test.go +40 -0
| @@ -431,3 +431,43 @@ func TestDestroyedProxyRejectsRequests(t *testing.T) { | |||
| 431 | 431 | t.Fatalf("unexpected bytes on wire: %v", err) | |
| 432 | 432 | } | |
| 433 | 433 | } | |
| 434 | + | ||
| 435 | + | func TestConcurrentDestroySendsOnce(t *testing.T) { | |
| 436 | + | c, p := pair(t) | |
| 437 | + | d, err := wlturbo.ConnectFromConn(c) | |
| 438 | + | if err != nil { | |
| 439 | + | t.Fatal(err) | |
| 440 | + | } | |
| 441 | + | defer d.Close() | |
| 442 | + | receiveRequest(t, p) | |
| 443 | + | for round := 0; round < 200; round++ { | |
| 444 | + | surface := core.NewSurface(d.Context()) | |
| 445 | + | surface.SetID(d.AllocateID()) | |
| 446 | + | d.Context().Register(surface) | |
| 447 | + | const callers = 8 | |
| 448 | + | start := make(chan struct{}) | |
| 449 | + | results := make(chan error, callers) | |
| 450 | + | for i := 0; i < callers; i++ { | |
| 451 | + | go func() { | |
| 452 | + | <-start | |
| 453 | + | results <- surface.Destroy() | |
| 454 | + | }() | |
| 455 | + | } | |
| 456 | + | close(start) | |
| 457 | + | ok := 0 | |
| 458 | + | for i := 0; i < callers; i++ { | |
| 459 | + | if <-results == nil { | |
| 460 | + | ok++ | |
| 461 | + | } | |
| 462 | + | } | |
| 463 | + | if ok != 1 { | |
| 464 | + | t.Fatalf("round %d: %d destroys succeeded, want 1", round, ok) | |
| 465 | + | } | |
| 466 | + | receiveRequest(t, p) | |
| 467 | + | p.SetReadDeadline(time.Now().Add(2 * time.Millisecond)) | |
| 468 | + | if n, err := p.Read(make([]byte, 8)); n != 0 { | |
| 469 | + | t.Fatalf("round %d: extra destroy on wire (%d bytes, %v)", round, n, err) | |
| 470 | + | } | |
| 471 | + | p.SetReadDeadline(time.Time{}) | |
| 472 | + | } | |
| 473 | + | } | |
| @@ -431,3 +431,43 @@ func TestDestroyedProxyRejectsRequests(t *testing.T) { | |||||
| 431 | t.Fatalf("unexpected bytes on wire: %v", err) | 431 | t.Fatalf("unexpected bytes on wire: %v", err) | ||
| 432 | } | 432 | } | ||
| 433 | } | 433 | } | ||
| 434 | + | ||||
| 435 | + | func TestConcurrentDestroySendsOnce(t *testing.T) { | |||
| 436 | + | c, p := pair(t) | |||
| 437 | + | d, err := wlturbo.ConnectFromConn(c) | |||
| 438 | + | if err != nil { | |||
| 439 | + | t.Fatal(err) | |||
| 440 | + | } | |||
| 441 | + | defer d.Close() | |||
| 442 | + | receiveRequest(t, p) | |||
| 443 | + | for round := 0; round < 200; round++ { | |||
| 444 | + | surface := core.NewSurface(d.Context()) | |||
| 445 | + | surface.SetID(d.AllocateID()) | |||
| 446 | + | d.Context().Register(surface) | |||
| 447 | + | const callers = 8 | |||
| 448 | + | start := make(chan struct{}) | |||
| 449 | + | results := make(chan error, callers) | |||
| 450 | + | for i := 0; i < callers; i++ { | |||
| 451 | + | go func() { | |||
| 452 | + | <-start | |||
| 453 | + | results <- surface.Destroy() | |||
| 454 | + | }() | |||
| 455 | + | } | |||
| 456 | + | close(start) | |||
| 457 | + | ok := 0 | |||
| 458 | + | for i := 0; i < callers; i++ { | |||
| 459 | + | if <-results == nil { | |||
| 460 | + | ok++ | |||
| 461 | + | } | |||
| 462 | + | } | |||
| 463 | + | if ok != 1 { | |||
| 464 | + | t.Fatalf("round %d: %d destroys succeeded, want 1", round, ok) | |||
| 465 | + | } | |||
| 466 | + | receiveRequest(t, p) | |||
| 467 | + | p.SetReadDeadline(time.Now().Add(2 * time.Millisecond)) | |||
| 468 | + | if n, err := p.Read(make([]byte, 8)); n != 0 { | |||
| 469 | + | t.Fatalf("round %d: extra destroy on wire (%d bytes, %v)", round, n, err) | |||
| 470 | + | } | |||
| 471 | + | p.SetReadDeadline(time.Time{}) | |||
| 472 | + | } | |||
| 473 | + | } | |||
M protocol/core/wayland_generated.go +18 -36
| @@ -808,10 +808,9 @@ func (o *Compositor) Release() error { | |||
| 808 | 808 | if err := o.Context().CheckProxy(o); err != nil { | |
| 809 | 809 | return err | |
| 810 | 810 | } | |
| 811 | - | if err := o.Context().SendRequest(o, 2); err != nil { | |
| 811 | + | if err := o.Context().SendDestructor(o, 2); err != nil { | |
| 812 | 812 | return err | |
| 813 | 813 | } | |
| 814 | - | o.Context().Unregister(o) | |
| 815 | 814 | return nil | |
| 816 | 815 | } | |
| 817 | 816 | ||
| @@ -867,10 +866,9 @@ func (o *ShmPool) Destroy() error { | |||
| 867 | 866 | if err := o.Context().CheckProxy(o); err != nil { | |
| 868 | 867 | return err | |
| 869 | 868 | } | |
| 870 | - | if err := o.Context().SendRequest(o, 1); err != nil { | |
| 869 | + | if err := o.Context().SendDestructor(o, 1); err != nil { | |
| 871 | 870 | return err | |
| 872 | 871 | } | |
| 873 | - | o.Context().Unregister(o) | |
| 874 | 872 | return nil | |
| 875 | 873 | } | |
| 876 | 874 | ||
| @@ -942,10 +940,9 @@ func (o *Shm) Release() error { | |||
| 942 | 940 | if err := o.Context().CheckProxy(o); err != nil { | |
| 943 | 941 | return err | |
| 944 | 942 | } | |
| 945 | - | if err := o.Context().SendRequest(o, 1); err != nil { | |
| 943 | + | if err := o.Context().SendDestructor(o, 1); err != nil { | |
| 946 | 944 | return err | |
| 947 | 945 | } | |
| 948 | - | o.Context().Unregister(o) | |
| 949 | 946 | return nil | |
| 950 | 947 | } | |
| 951 | 948 | ||
| @@ -1020,10 +1017,9 @@ func (o *Buffer) Destroy() error { | |||
| 1020 | 1017 | if err := o.Context().CheckProxy(o); err != nil { | |
| 1021 | 1018 | return err | |
| 1022 | 1019 | } | |
| 1023 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 1020 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 1024 | 1021 | return err | |
| 1025 | 1022 | } | |
| 1026 | - | o.Context().Unregister(o) | |
| 1027 | 1023 | return nil | |
| 1028 | 1024 | } | |
| 1029 | 1025 | ||
| @@ -1122,10 +1118,9 @@ func (o *DataOffer) Destroy() error { | |||
| 1122 | 1118 | if err := o.Context().CheckProxy(o); err != nil { | |
| 1123 | 1119 | return err | |
| 1124 | 1120 | } | |
| 1125 | - | if err := o.Context().SendRequest(o, 2); err != nil { | |
| 1121 | + | if err := o.Context().SendDestructor(o, 2); err != nil { | |
| 1126 | 1122 | return err | |
| 1127 | 1123 | } | |
| 1128 | - | o.Context().Unregister(o) | |
| 1129 | 1124 | return nil | |
| 1130 | 1125 | } | |
| 1131 | 1126 | ||
| @@ -1300,10 +1295,9 @@ func (o *DataSource) Destroy() error { | |||
| 1300 | 1295 | if err := o.Context().CheckProxy(o); err != nil { | |
| 1301 | 1296 | return err | |
| 1302 | 1297 | } | |
| 1303 | - | if err := o.Context().SendRequest(o, 1); err != nil { | |
| 1298 | + | if err := o.Context().SendDestructor(o, 1); err != nil { | |
| 1304 | 1299 | return err | |
| 1305 | 1300 | } | |
| 1306 | - | o.Context().Unregister(o) | |
| 1307 | 1301 | return nil | |
| 1308 | 1302 | } | |
| 1309 | 1303 | ||
| @@ -1589,10 +1583,9 @@ func (o *DataDevice) Release() error { | |||
| 1589 | 1583 | if err := o.Context().CheckProxy(o); err != nil { | |
| 1590 | 1584 | return err | |
| 1591 | 1585 | } | |
| 1592 | - | if err := o.Context().SendRequest(o, 2); err != nil { | |
| 1586 | + | if err := o.Context().SendDestructor(o, 2); err != nil { | |
| 1593 | 1587 | return err | |
| 1594 | 1588 | } | |
| 1595 | - | o.Context().Unregister(o) | |
| 1596 | 1589 | return nil | |
| 1597 | 1590 | } | |
| 1598 | 1591 | ||
| @@ -1862,10 +1855,9 @@ func (o *DataDeviceManager) Release() error { | |||
| 1862 | 1855 | if err := o.Context().CheckProxy(o); err != nil { | |
| 1863 | 1856 | return err | |
| 1864 | 1857 | } | |
| 1865 | - | if err := o.Context().SendRequest(o, 2); err != nil { | |
| 1858 | + | if err := o.Context().SendDestructor(o, 2); err != nil { | |
| 1866 | 1859 | return err | |
| 1867 | 1860 | } | |
| 1868 | - | o.Context().Unregister(o) | |
| 1869 | 1861 | return nil | |
| 1870 | 1862 | } | |
| 1871 | 1863 | ||
| @@ -2232,10 +2224,9 @@ func (o *Surface) Destroy() error { | |||
| 2232 | 2224 | if err := o.Context().CheckProxy(o); err != nil { | |
| 2233 | 2225 | return err | |
| 2234 | 2226 | } | |
| 2235 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 2227 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 2236 | 2228 | return err | |
| 2237 | 2229 | } | |
| 2238 | - | o.Context().Unregister(o) | |
| 2239 | 2230 | return nil | |
| 2240 | 2231 | } | |
| 2241 | 2232 | ||
| @@ -2595,10 +2586,9 @@ func (o *Seat) Release() error { | |||
| 2595 | 2586 | if err := o.Context().CheckProxy(o); err != nil { | |
| 2596 | 2587 | return err | |
| 2597 | 2588 | } | |
| 2598 | - | if err := o.Context().SendRequest(o, 3); err != nil { | |
| 2589 | + | if err := o.Context().SendDestructor(o, 3); err != nil { | |
| 2599 | 2590 | return err | |
| 2600 | 2591 | } | |
| 2601 | - | o.Context().Unregister(o) | |
| 2602 | 2592 | return nil | |
| 2603 | 2593 | } | |
| 2604 | 2594 | ||
| @@ -2730,10 +2720,9 @@ func (o *Pointer) Release() error { | |||
| 2730 | 2720 | if err := o.Context().CheckProxy(o); err != nil { | |
| 2731 | 2721 | return err | |
| 2732 | 2722 | } | |
| 2733 | - | if err := o.Context().SendRequest(o, 1); err != nil { | |
| 2723 | + | if err := o.Context().SendDestructor(o, 1); err != nil { | |
| 2734 | 2724 | return err | |
| 2735 | 2725 | } | |
| 2736 | - | o.Context().Unregister(o) | |
| 2737 | 2726 | return nil | |
| 2738 | 2727 | } | |
| 2739 | 2728 | ||
| @@ -3169,10 +3158,9 @@ func (o *Keyboard) Release() error { | |||
| 3169 | 3158 | if err := o.Context().CheckProxy(o); err != nil { | |
| 3170 | 3159 | return err | |
| 3171 | 3160 | } | |
| 3172 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 3161 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 3173 | 3162 | return err | |
| 3174 | 3163 | } | |
| 3175 | - | o.Context().Unregister(o) | |
| 3176 | 3164 | return nil | |
| 3177 | 3165 | } | |
| 3178 | 3166 | ||
| @@ -3425,10 +3413,9 @@ func (o *Touch) Release() error { | |||
| 3425 | 3413 | if err := o.Context().CheckProxy(o); err != nil { | |
| 3426 | 3414 | return err | |
| 3427 | 3415 | } | |
| 3428 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 3416 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 3429 | 3417 | return err | |
| 3430 | 3418 | } | |
| 3431 | - | o.Context().Unregister(o) | |
| 3432 | 3419 | return nil | |
| 3433 | 3420 | } | |
| 3434 | 3421 | ||
| @@ -3705,10 +3692,9 @@ func (o *Output) Release() error { | |||
| 3705 | 3692 | if err := o.Context().CheckProxy(o); err != nil { | |
| 3706 | 3693 | return err | |
| 3707 | 3694 | } | |
| 3708 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 3695 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 3709 | 3696 | return err | |
| 3710 | 3697 | } | |
| 3711 | - | o.Context().Unregister(o) | |
| 3712 | 3698 | return nil | |
| 3713 | 3699 | } | |
| 3714 | 3700 | ||
| @@ -3943,10 +3929,9 @@ func (o *Region) Destroy() error { | |||
| 3943 | 3929 | if err := o.Context().CheckProxy(o); err != nil { | |
| 3944 | 3930 | return err | |
| 3945 | 3931 | } | |
| 3946 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 3932 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 3947 | 3933 | return err | |
| 3948 | 3934 | } | |
| 3949 | - | o.Context().Unregister(o) | |
| 3950 | 3935 | return nil | |
| 3951 | 3936 | } | |
| 3952 | 3937 | ||
| @@ -4008,10 +3993,9 @@ func (o *Subcompositor) Destroy() error { | |||
| 4008 | 3993 | if err := o.Context().CheckProxy(o); err != nil { | |
| 4009 | 3994 | return err | |
| 4010 | 3995 | } | |
| 4011 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 3996 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 4012 | 3997 | return err | |
| 4013 | 3998 | } | |
| 4014 | - | o.Context().Unregister(o) | |
| 4015 | 3999 | return nil | |
| 4016 | 4000 | } | |
| 4017 | 4001 | ||
| @@ -4075,10 +4059,9 @@ func (o *Subsurface) Destroy() error { | |||
| 4075 | 4059 | if err := o.Context().CheckProxy(o); err != nil { | |
| 4076 | 4060 | return err | |
| 4077 | 4061 | } | |
| 4078 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 4062 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 4079 | 4063 | return err | |
| 4080 | 4064 | } | |
| 4081 | - | o.Context().Unregister(o) | |
| 4082 | 4065 | return nil | |
| 4083 | 4066 | } | |
| 4084 | 4067 | ||
| @@ -4181,10 +4164,9 @@ func (o *Fixes) Destroy() error { | |||
| 4181 | 4164 | if err := o.Context().CheckProxy(o); err != nil { | |
| 4182 | 4165 | return err | |
| 4183 | 4166 | } | |
| 4184 | - | if err := o.Context().SendRequest(o, 0); err != nil { | |
| 4167 | + | if err := o.Context().SendDestructor(o, 0); err != nil { | |
| 4185 | 4168 | return err | |
| 4186 | 4169 | } | |
| 4187 | - | o.Context().Unregister(o) | |
| 4188 | 4170 | return nil | |
| 4189 | 4171 | } | |
| 4190 | 4172 | ||
| @@ -808,10 +808,9 @@ func (o *Compositor) Release() error { | |||||
| 808 | if err := o.Context().CheckProxy(o); err != nil { | 808 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 809 | return err | 809 | return err | ||
| 810 | } | 810 | } | ||
| 811 | - | if err := o.Context().SendRequest(o, 2); err != nil { | 811 | + | if err := o.Context().SendDestructor(o, 2); err != nil { |
| 812 | return err | 812 | return err | ||
| 813 | } | 813 | } | ||
| 814 | - | o.Context().Unregister(o) | |||
| 815 | return nil | 814 | return nil | ||
| 816 | } | 815 | } | ||
| 817 | 816 | ||||
| @@ -867,10 +866,9 @@ func (o *ShmPool) Destroy() error { | |||||
| 867 | if err := o.Context().CheckProxy(o); err != nil { | 866 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 868 | return err | 867 | return err | ||
| 869 | } | 868 | } | ||
| 870 | - | if err := o.Context().SendRequest(o, 1); err != nil { | 869 | + | if err := o.Context().SendDestructor(o, 1); err != nil { |
| 871 | return err | 870 | return err | ||
| 872 | } | 871 | } | ||
| 873 | - | o.Context().Unregister(o) | |||
| 874 | return nil | 872 | return nil | ||
| 875 | } | 873 | } | ||
| 876 | 874 | ||||
| @@ -942,10 +940,9 @@ func (o *Shm) Release() error { | |||||
| 942 | if err := o.Context().CheckProxy(o); err != nil { | 940 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 943 | return err | 941 | return err | ||
| 944 | } | 942 | } | ||
| 945 | - | if err := o.Context().SendRequest(o, 1); err != nil { | 943 | + | if err := o.Context().SendDestructor(o, 1); err != nil { |
| 946 | return err | 944 | return err | ||
| 947 | } | 945 | } | ||
| 948 | - | o.Context().Unregister(o) | |||
| 949 | return nil | 946 | return nil | ||
| 950 | } | 947 | } | ||
| 951 | 948 | ||||
| @@ -1020,10 +1017,9 @@ func (o *Buffer) Destroy() error { | |||||
| 1020 | if err := o.Context().CheckProxy(o); err != nil { | 1017 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 1021 | return err | 1018 | return err | ||
| 1022 | } | 1019 | } | ||
| 1023 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 1020 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 1024 | return err | 1021 | return err | ||
| 1025 | } | 1022 | } | ||
| 1026 | - | o.Context().Unregister(o) | |||
| 1027 | return nil | 1023 | return nil | ||
| 1028 | } | 1024 | } | ||
| 1029 | 1025 | ||||
| @@ -1122,10 +1118,9 @@ func (o *DataOffer) Destroy() error { | |||||
| 1122 | if err := o.Context().CheckProxy(o); err != nil { | 1118 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 1123 | return err | 1119 | return err | ||
| 1124 | } | 1120 | } | ||
| 1125 | - | if err := o.Context().SendRequest(o, 2); err != nil { | 1121 | + | if err := o.Context().SendDestructor(o, 2); err != nil { |
| 1126 | return err | 1122 | return err | ||
| 1127 | } | 1123 | } | ||
| 1128 | - | o.Context().Unregister(o) | |||
| 1129 | return nil | 1124 | return nil | ||
| 1130 | } | 1125 | } | ||
| 1131 | 1126 | ||||
| @@ -1300,10 +1295,9 @@ func (o *DataSource) Destroy() error { | |||||
| 1300 | if err := o.Context().CheckProxy(o); err != nil { | 1295 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 1301 | return err | 1296 | return err | ||
| 1302 | } | 1297 | } | ||
| 1303 | - | if err := o.Context().SendRequest(o, 1); err != nil { | 1298 | + | if err := o.Context().SendDestructor(o, 1); err != nil { |
| 1304 | return err | 1299 | return err | ||
| 1305 | } | 1300 | } | ||
| 1306 | - | o.Context().Unregister(o) | |||
| 1307 | return nil | 1301 | return nil | ||
| 1308 | } | 1302 | } | ||
| 1309 | 1303 | ||||
| @@ -1589,10 +1583,9 @@ func (o *DataDevice) Release() error { | |||||
| 1589 | if err := o.Context().CheckProxy(o); err != nil { | 1583 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 1590 | return err | 1584 | return err | ||
| 1591 | } | 1585 | } | ||
| 1592 | - | if err := o.Context().SendRequest(o, 2); err != nil { | 1586 | + | if err := o.Context().SendDestructor(o, 2); err != nil { |
| 1593 | return err | 1587 | return err | ||
| 1594 | } | 1588 | } | ||
| 1595 | - | o.Context().Unregister(o) | |||
| 1596 | return nil | 1589 | return nil | ||
| 1597 | } | 1590 | } | ||
| 1598 | 1591 | ||||
| @@ -1862,10 +1855,9 @@ func (o *DataDeviceManager) Release() error { | |||||
| 1862 | if err := o.Context().CheckProxy(o); err != nil { | 1855 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 1863 | return err | 1856 | return err | ||
| 1864 | } | 1857 | } | ||
| 1865 | - | if err := o.Context().SendRequest(o, 2); err != nil { | 1858 | + | if err := o.Context().SendDestructor(o, 2); err != nil { |
| 1866 | return err | 1859 | return err | ||
| 1867 | } | 1860 | } | ||
| 1868 | - | o.Context().Unregister(o) | |||
| 1869 | return nil | 1861 | return nil | ||
| 1870 | } | 1862 | } | ||
| 1871 | 1863 | ||||
| @@ -2232,10 +2224,9 @@ func (o *Surface) Destroy() error { | |||||
| 2232 | if err := o.Context().CheckProxy(o); err != nil { | 2224 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 2233 | return err | 2225 | return err | ||
| 2234 | } | 2226 | } | ||
| 2235 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 2227 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 2236 | return err | 2228 | return err | ||
| 2237 | } | 2229 | } | ||
| 2238 | - | o.Context().Unregister(o) | |||
| 2239 | return nil | 2230 | return nil | ||
| 2240 | } | 2231 | } | ||
| 2241 | 2232 | ||||
| @@ -2595,10 +2586,9 @@ func (o *Seat) Release() error { | |||||
| 2595 | if err := o.Context().CheckProxy(o); err != nil { | 2586 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 2596 | return err | 2587 | return err | ||
| 2597 | } | 2588 | } | ||
| 2598 | - | if err := o.Context().SendRequest(o, 3); err != nil { | 2589 | + | if err := o.Context().SendDestructor(o, 3); err != nil { |
| 2599 | return err | 2590 | return err | ||
| 2600 | } | 2591 | } | ||
| 2601 | - | o.Context().Unregister(o) | |||
| 2602 | return nil | 2592 | return nil | ||
| 2603 | } | 2593 | } | ||
| 2604 | 2594 | ||||
| @@ -2730,10 +2720,9 @@ func (o *Pointer) Release() error { | |||||
| 2730 | if err := o.Context().CheckProxy(o); err != nil { | 2720 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 2731 | return err | 2721 | return err | ||
| 2732 | } | 2722 | } | ||
| 2733 | - | if err := o.Context().SendRequest(o, 1); err != nil { | 2723 | + | if err := o.Context().SendDestructor(o, 1); err != nil { |
| 2734 | return err | 2724 | return err | ||
| 2735 | } | 2725 | } | ||
| 2736 | - | o.Context().Unregister(o) | |||
| 2737 | return nil | 2726 | return nil | ||
| 2738 | } | 2727 | } | ||
| 2739 | 2728 | ||||
| @@ -3169,10 +3158,9 @@ func (o *Keyboard) Release() error { | |||||
| 3169 | if err := o.Context().CheckProxy(o); err != nil { | 3158 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 3170 | return err | 3159 | return err | ||
| 3171 | } | 3160 | } | ||
| 3172 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 3161 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 3173 | return err | 3162 | return err | ||
| 3174 | } | 3163 | } | ||
| 3175 | - | o.Context().Unregister(o) | |||
| 3176 | return nil | 3164 | return nil | ||
| 3177 | } | 3165 | } | ||
| 3178 | 3166 | ||||
| @@ -3425,10 +3413,9 @@ func (o *Touch) Release() error { | |||||
| 3425 | if err := o.Context().CheckProxy(o); err != nil { | 3413 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 3426 | return err | 3414 | return err | ||
| 3427 | } | 3415 | } | ||
| 3428 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 3416 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 3429 | return err | 3417 | return err | ||
| 3430 | } | 3418 | } | ||
| 3431 | - | o.Context().Unregister(o) | |||
| 3432 | return nil | 3419 | return nil | ||
| 3433 | } | 3420 | } | ||
| 3434 | 3421 | ||||
| @@ -3705,10 +3692,9 @@ func (o *Output) Release() error { | |||||
| 3705 | if err := o.Context().CheckProxy(o); err != nil { | 3692 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 3706 | return err | 3693 | return err | ||
| 3707 | } | 3694 | } | ||
| 3708 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 3695 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 3709 | return err | 3696 | return err | ||
| 3710 | } | 3697 | } | ||
| 3711 | - | o.Context().Unregister(o) | |||
| 3712 | return nil | 3698 | return nil | ||
| 3713 | } | 3699 | } | ||
| 3714 | 3700 | ||||
| @@ -3943,10 +3929,9 @@ func (o *Region) Destroy() error { | |||||
| 3943 | if err := o.Context().CheckProxy(o); err != nil { | 3929 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 3944 | return err | 3930 | return err | ||
| 3945 | } | 3931 | } | ||
| 3946 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 3932 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 3947 | return err | 3933 | return err | ||
| 3948 | } | 3934 | } | ||
| 3949 | - | o.Context().Unregister(o) | |||
| 3950 | return nil | 3935 | return nil | ||
| 3951 | } | 3936 | } | ||
| 3952 | 3937 | ||||
| @@ -4008,10 +3993,9 @@ func (o *Subcompositor) Destroy() error { | |||||
| 4008 | if err := o.Context().CheckProxy(o); err != nil { | 3993 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 4009 | return err | 3994 | return err | ||
| 4010 | } | 3995 | } | ||
| 4011 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 3996 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 4012 | return err | 3997 | return err | ||
| 4013 | } | 3998 | } | ||
| 4014 | - | o.Context().Unregister(o) | |||
| 4015 | return nil | 3999 | return nil | ||
| 4016 | } | 4000 | } | ||
| 4017 | 4001 | ||||
| @@ -4075,10 +4059,9 @@ func (o *Subsurface) Destroy() error { | |||||
| 4075 | if err := o.Context().CheckProxy(o); err != nil { | 4059 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 4076 | return err | 4060 | return err | ||
| 4077 | } | 4061 | } | ||
| 4078 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 4062 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 4079 | return err | 4063 | return err | ||
| 4080 | } | 4064 | } | ||
| 4081 | - | o.Context().Unregister(o) | |||
| 4082 | return nil | 4065 | return nil | ||
| 4083 | } | 4066 | } | ||
| 4084 | 4067 | ||||
| @@ -4181,10 +4164,9 @@ func (o *Fixes) Destroy() error { | |||||
| 4181 | if err := o.Context().CheckProxy(o); err != nil { | 4164 | if err := o.Context().CheckProxy(o); err != nil { | ||
| 4182 | return err | 4165 | return err | ||
| 4183 | } | 4166 | } | ||
| 4184 | - | if err := o.Context().SendRequest(o, 0); err != nil { | 4167 | + | if err := o.Context().SendDestructor(o, 0); err != nil { |
| 4185 | return err | 4168 | return err | ||
| 4186 | } | 4169 | } | ||
| 4187 | - | o.Context().Unregister(o) | |||
| 4188 | return nil | 4170 | return nil | ||
| 4189 | } | 4171 | } | ||
| 4190 | 4172 | ||||