Update upstream source from tag 'upstream/1.63.92'
Update to upstream version '1.63.92'
with Debian dir dee4109b12284a8e9a85d44ce5ee7a260e93b5c8
Iain Lane
4 years ago
0 | Version 1.63.92 | |
1 | --------------- | |
2 | ||
3 | - Closed bugs and merge requests: | |
4 | * object: Use g_irepository_get_object_gtype_interfaces [Colin Walters, Philip | |
5 | Chimento, #55, !52] | |
6 | * Add -fno-semantic-interposition to -Bsymbolic-functions [Jan Alexander | |
7 | Steffens (heftig), #303, !397] | |
8 | * examples: add a dbus-client and dbus-service example [Andy Holmes, !398] | |
9 | * Various GNOME Shell crashes during GC, mozjs68 regression [Jan Alexander | |
10 | Steffens (heftig), Philip Chimento, #301, !396] | |
11 | ||
0 | 12 | Version 1.63.91 |
1 | 13 | --------------- |
2 | 14 |
0 | 'use strict'; | |
1 | ||
2 | const GLib = imports.gi.GLib; | |
3 | const Gio = imports.gi.Gio; | |
4 | ||
5 | ||
6 | /* | |
7 | * An XML DBus Interface | |
8 | */ | |
9 | const ifaceXml = ` | |
10 | <node> | |
11 | <interface name="org.gnome.gjs.Test"> | |
12 | <method name="SimpleMethod"/> | |
13 | <method name="ComplexMethod"> | |
14 | <arg type="s" direction="in" name="input"/> | |
15 | <arg type="u" direction="out" name="length"/> | |
16 | </method> | |
17 | <signal name="TestSignal"> | |
18 | <arg name="type" type="s"/> | |
19 | <arg name="value" type="b"/> | |
20 | </signal> | |
21 | <property name="ReadOnlyProperty" type="s" access="read"/> | |
22 | <property name="ReadWriteProperty" type="b" access="readwrite"/> | |
23 | </interface> | |
24 | </node>`; | |
25 | ||
26 | ||
27 | ||
28 | // Pass the XML string to make a re-usable proxy class for an interface proxies. | |
29 | const TestProxy = Gio.DBusProxy.makeProxyWrapper(ifaceXml); | |
30 | ||
31 | ||
32 | let proxy = null; | |
33 | let proxySignalId = 0; | |
34 | let proxyPropId = 0; | |
35 | ||
36 | ||
37 | // Watching a name on DBus. Another option is to create a proxy with the | |
38 | // `Gio.DBusProxyFlags.DO_NOT_AUTO_START` flag and watch the `g-name-owner` | |
39 | // property. | |
40 | function onNameAppeared(connection, name, _owner) { | |
41 | print(`"${name}" appeared on the session bus`); | |
42 | ||
43 | // If creating a proxy synchronously, errors will be thrown as normal | |
44 | try { | |
45 | proxy = new TestProxy( | |
46 | Gio.DBus.session, | |
47 | 'org.gnome.gjs.Test', | |
48 | '/org/gnome/gjs/Test' | |
49 | ); | |
50 | } catch (e) { | |
51 | logError(e); | |
52 | return; | |
53 | } | |
54 | ||
55 | ||
56 | // Proxy wrapper signals use the special functions `connectSignal()` and | |
57 | // `disconnectSignal()` to avoid conflicting with regular GObject signals. | |
58 | proxySignalId = proxy.connectSignal('TestSignal', (proxy_, name_, args) => { | |
59 | print(`TestSignal: ${args[0]}, ${args[1]}`); | |
60 | }); | |
61 | ||
62 | ||
63 | // To watch property changes, you can connect to the `g-properties-changed` | |
64 | // GObject signal with `connect()` | |
65 | proxyPropId = proxy.connect('g-properties-changed', (proxy_, changed, invalidated) => { | |
66 | for (let [prop, value] of Object.entries(changed.deepUnpack())) | |
67 | print(`Property '${prop}' changed to '${value.deepUnpack()}'`); | |
68 | ||
69 | for (let prop of invalidated) | |
70 | print(`Property '${prop}' invalidated`); | |
71 | }); | |
72 | ||
73 | ||
74 | // Reading and writing properties is straight-forward | |
75 | print(`ReadOnlyProperty: ${proxy.ReadOnlyProperty}`); | |
76 | ||
77 | print(`ReadWriteProperty: ${proxy.ReadWriteProperty}`); | |
78 | ||
79 | proxy.ReadWriteProperty = !proxy.ReadWriteProperty; | |
80 | print(`ReadWriteProperty: ${proxy.ReadWriteProperty}`); | |
81 | ||
82 | ||
83 | // Both synchronous and asynchronous functions will be generated | |
84 | try { | |
85 | let value = proxy.SimpleMethodSync(); | |
86 | ||
87 | print(`SimpleMethod: ${value}`); | |
88 | } catch (e) { | |
89 | logError(`SimpleMethod: ${e.message}`); | |
90 | } | |
91 | ||
92 | proxy.ComplexMethodRemote('input string', (value, error, fdList) => { | |
93 | ||
94 | // If @error is not `null`, then an error occurred | |
95 | if (error !== null) { | |
96 | logError(error); | |
97 | return; | |
98 | } | |
99 | ||
100 | print(`ComplexMethod: ${value}`); | |
101 | ||
102 | // Methods that return file descriptors are fairly rare, so you should | |
103 | // know to expect one or not. | |
104 | if (fdList !== null) { | |
105 | // | |
106 | } | |
107 | }); | |
108 | } | |
109 | ||
110 | function onNameVanished(connection, name) { | |
111 | print(`"${name}" vanished from the session bus`); | |
112 | ||
113 | if (proxy !== null) { | |
114 | proxy.disconnectSignal(proxySignalId); | |
115 | proxy.disconnect(proxyPropId); | |
116 | proxy = null; | |
117 | } | |
118 | } | |
119 | ||
120 | let busWatchId = Gio.bus_watch_name( | |
121 | Gio.BusType.SESSION, | |
122 | 'org.gnome.gjs.Test', | |
123 | Gio.BusNameWatcherFlags.NONE, | |
124 | onNameAppeared, | |
125 | onNameVanished | |
126 | ); | |
127 | ||
128 | // Start an event loop | |
129 | let loop = GLib.MainLoop.new(null, false); | |
130 | loop.run(); | |
131 | ||
132 | // Unwatching names works just like disconnecting signal handlers. | |
133 | Gio.bus_unown_name(busWatchId); | |
134 | ||
135 | ||
136 | /* Asynchronous Usage | |
137 | * | |
138 | * Below is the alternative, asynchronous usage of proxy wrappers. If creating | |
139 | * a proxy asynchronously, you should not consider the proxy ready to use until | |
140 | * the callback is invoked without error. | |
141 | */ | |
142 | proxy = null; | |
143 | ||
144 | new TestProxy( | |
145 | Gio.DBus.session, | |
146 | 'org.gnome.gjs.Test', | |
147 | '/org/gnome/gjs/Test', | |
148 | (sourceObj, error) => { | |
149 | // If @error is not `null` it will be an Error object indicating the | |
150 | // failure. @proxy will be `null` in this case. | |
151 | if (error !== null) { | |
152 | logError(error); | |
153 | return; | |
154 | } | |
155 | ||
156 | // At this point the proxy is initialized and you can start calling | |
157 | // functions, using properties and so on. | |
158 | proxy = sourceObj; | |
159 | print(`ReadOnlyProperty: ${proxy.ReadOnlyProperty}`); | |
160 | }, | |
161 | // Optional Gio.Cancellable object. Pass `null` if you need to pass flags. | |
162 | null, | |
163 | // Optional flags passed to the Gio.DBusProxy constructor | |
164 | Gio.DBusProxyFlags.NONE | |
165 | ); | |
166 |
0 | 'use strict'; | |
1 | ||
2 | const GLib = imports.gi.GLib; | |
3 | const Gio = imports.gi.Gio; | |
4 | ||
5 | ||
6 | /* | |
7 | * An XML DBus Interface | |
8 | */ | |
9 | const ifaceXml = ` | |
10 | <node> | |
11 | <interface name="org.gnome.gjs.Test"> | |
12 | <method name="SimpleMethod"/> | |
13 | <method name="ComplexMethod"> | |
14 | <arg type="s" direction="in" name="input"/> | |
15 | <arg type="u" direction="out" name="length"/> | |
16 | </method> | |
17 | <signal name="TestSignal"> | |
18 | <arg name="type" type="s"/> | |
19 | <arg name="value" type="b"/> | |
20 | </signal> | |
21 | <property name="ReadOnlyProperty" type="s" access="read"/> | |
22 | <property name="ReadWriteProperty" type="b" access="readwrite"/> | |
23 | </interface> | |
24 | </node>`; | |
25 | ||
26 | ||
27 | // An example of the service-side implementation of the above interface. | |
28 | class Service { | |
29 | ||
30 | constructor() { | |
31 | this.dbus = Gio.DBusExportedObject.wrapJSObject(ifaceXml, this); | |
32 | } | |
33 | ||
34 | // Properties | |
35 | get ReadOnlyProperty() { | |
36 | return 'a string'; | |
37 | } | |
38 | ||
39 | get ReadWriteProperty() { | |
40 | if (this._readWriteProperty === undefined) | |
41 | return false; | |
42 | ||
43 | return this._readWriteProperty; | |
44 | } | |
45 | ||
46 | set ReadWriteProperty(value) { | |
47 | if (this.ReadWriteProperty !== value) { | |
48 | this._readWriteProperty = value; | |
49 | ||
50 | // Emitting property changes over DBus | |
51 | this.dbus.emit_property_changed( | |
52 | 'ReadWriteProperty', | |
53 | new GLib.Variant('b', value) | |
54 | ); | |
55 | } | |
56 | } | |
57 | ||
58 | // Methods | |
59 | SimpleMethod() { | |
60 | print('SimpleMethod() invoked'); | |
61 | } | |
62 | ||
63 | ComplexMethod(input) { | |
64 | print(`ComplexMethod() invoked with "${input}"`); | |
65 | ||
66 | return input.length; | |
67 | } | |
68 | ||
69 | // Signals | |
70 | emitTestSignal() { | |
71 | this.dbus.emit_signal( | |
72 | 'TestSignal', | |
73 | new GLib.Variant('(sb)', ['string', false]) | |
74 | ); | |
75 | } | |
76 | } | |
77 | ||
78 | ||
79 | // Once you've created an instance of your service, you will want to own a name | |
80 | // on the bus so clients can connect to it. | |
81 | let serviceObj = new Service(); | |
82 | let serviceSignalId = 0; | |
83 | ||
84 | ||
85 | function onBusAcquired(connection, _name) { | |
86 | // At this point you have acquired a connection to the bus, and you should | |
87 | // export your interfaces now. | |
88 | serviceObj.dbus.export(connection, '/org/gnome/gjs/Test'); | |
89 | } | |
90 | ||
91 | function onNameAcquired(_connection, _name) { | |
92 | // Clients will typically start connecting and using your interface now. | |
93 | ||
94 | // Emit the TestSignal every few seconds | |
95 | serviceSignalId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 3, () => { | |
96 | serviceObj.emitTestSignal(); | |
97 | ||
98 | return GLib.SOURCE_CONTINUE; | |
99 | }); | |
100 | } | |
101 | ||
102 | function onNameLost(_connection, _name) { | |
103 | // Clients will know not to call methods on your interface now. Usually this | |
104 | // callback will only be invoked if you try to own a name on DBus that | |
105 | // already has an owner. | |
106 | ||
107 | // Stop emitting the test signal | |
108 | if (serviceSignalId > 0) { | |
109 | GLib.Source.remove(serviceSignalId); | |
110 | serviceSignalId = 0; | |
111 | } | |
112 | } | |
113 | ||
114 | let ownerId = Gio.bus_own_name( | |
115 | Gio.BusType.SESSION, | |
116 | 'org.gnome.gjs.Test', | |
117 | Gio.BusNameOwnerFlags.NONE, | |
118 | onBusAcquired, | |
119 | onNameAcquired, | |
120 | onNameLost | |
121 | ); | |
122 | ||
123 | ||
124 | // Start an event loop | |
125 | let loop = GLib.MainLoop.new(null, false); | |
126 | loop.run(); | |
127 | ||
128 | // Unowning names works just like disconnecting, but note that `onNameLost()` | |
129 | // will not be invoked in this case. | |
130 | Gio.bus_unown_name(ownerId); | |
131 | ||
132 | if (serviceSignalId > 0) { | |
133 | GLib.Source.remove(serviceSignalId); | |
134 | serviceSignalId = 0; | |
135 | } | |
136 |
666 | 666 | canonicalize_key(canonical_name); |
667 | 667 | } |
668 | 668 | |
669 | GjsAutoFree<GType> interfaces = g_type_interfaces(m_gtype, &n_interfaces); | |
669 | GIInterfaceInfo** interfaces; | |
670 | g_irepository_get_object_gtype_interfaces(nullptr, m_gtype, &n_interfaces, | |
671 | &interfaces); | |
670 | 672 | |
671 | 673 | /* Fallback to GType system for non custom GObjects with no GI information |
672 | 674 | */ |
678 | 680 | return lazy_define_gobject_property(cx, obj, id, resolved, name); |
679 | 681 | |
680 | 682 | for (i = 0; i < n_interfaces; i++) { |
681 | if (!G_TYPE_IS_CLASSED(interfaces[i])) | |
683 | GType iface_gtype = | |
684 | g_registered_type_info_get_g_type(interfaces[i]); | |
685 | if (!G_TYPE_IS_CLASSED(iface_gtype)) | |
682 | 686 | continue; |
683 | 687 | |
684 | GjsAutoTypeClass<GObjectClass> iclass(interfaces[i]); | |
688 | GjsAutoTypeClass<GObjectClass> iclass(iface_gtype); | |
685 | 689 | |
686 | 690 | if (g_object_class_find_property(iclass, canonical_name)) |
687 | 691 | return lazy_define_gobject_property(cx, obj, id, resolved, name); |
689 | 693 | } |
690 | 694 | |
691 | 695 | for (i = 0; i < n_interfaces; i++) { |
692 | GjsAutoInterfaceInfo iface_info = | |
693 | g_irepository_find_by_gtype(nullptr, interfaces[i]); | |
694 | if (!iface_info) | |
695 | continue; | |
696 | ||
696 | GIInterfaceInfo* iface_info = interfaces[i]; | |
697 | 697 | GjsAutoFunctionInfo method_info = |
698 | 698 | g_interface_info_find_method(iface_info, name); |
699 | 699 | if (method_info) { |
881 | 881 | |
882 | 882 | /** |
883 | 883 | * Search through any interfaces implemented by the GType; |
884 | * this could be done better. See | |
885 | * https://bugzilla.gnome.org/show_bug.cgi?id=632922 | |
884 | * See https://bugzilla.gnome.org/show_bug.cgi?id=632922 | |
885 | * for background on why we need to do this. | |
886 | 886 | */ |
887 | 887 | if (!method_info) |
888 | 888 | return resolve_no_info(context, obj, id, resolved, name, |
1070 | 1070 | ObjectInstance::gobj_dispose_notify(void) |
1071 | 1071 | { |
1072 | 1072 | m_gobj_disposed = true; |
1073 | unlink(); | |
1074 | 1073 | } |
1075 | 1074 | |
1076 | 1075 | void ObjectInstance::iterate_wrapped_gobjects( |
193 | 193 | JS_ShutDown(); |
194 | 194 | } |
195 | 195 | |
196 | operator bool() const { | |
197 | return true; | |
198 | } | |
196 | explicit operator bool() const { return true; } | |
199 | 197 | }; |
200 | 198 | |
201 | 199 | static GjsInit gjs_is_inited; |
228 | 228 | inline bool operator!=(std::nullptr_t) const { return !(*this == nullptr); } |
229 | 229 | |
230 | 230 | /* Likewise the truth value does not require a read barrier */ |
231 | inline operator bool() const { return *this != nullptr; } | |
231 | inline explicit operator bool() const { return *this != nullptr; } | |
232 | 232 | |
233 | 233 | /* You can get a Handle<T> if the thing is rooted, so that you can use this |
234 | 234 | * wrapper with stack rooting. However, you must not do this if the |
0 | project('gjs', 'cpp', 'c', version: '1.63.91', license: ['MIT', 'LGPL2+'], | |
0 | project('gjs', 'cpp', 'c', version: '1.63.92', license: ['MIT', 'LGPL2+'], | |
1 | 1 | meson_version: '>= 0.50.0', |
2 | 2 | default_options: ['cpp_std=c++14', 'c_std=c99', 'warning_level=2']) |
3 | 3 | |
59 | 59 | -Dbsymbolic_functions=false''') |
60 | 60 | endif |
61 | 61 | add_project_link_arguments('-Bsymbolic-functions', language: ['cpp', 'c']) |
62 | if cc.has_argument('-fno-semantic-interposition') | |
63 | add_project_arguments('-fno-semantic-interposition', language: 'c') | |
64 | endif | |
65 | if cxx.has_argument('-fno-semantic-interposition') | |
66 | add_project_arguments('-fno-semantic-interposition', language: 'cpp') | |
67 | endif | |
62 | 68 | endif |
63 | 69 | endif |
64 | 70 |
28 | 28 | |
29 | 29 | #include <glib-object.h> |
30 | 30 | #include <glib.h> |
31 | #include <glib/gstdio.h> // for g_unlink | |
31 | 32 | |
32 | 33 | #include <js/CharacterEncoding.h> |
33 | 34 | #include <js/RootingAPI.h> |
367 | 368 | nullptr)); |
368 | 369 | GjsProfiler *profiler = gjs_context_get_profiler(context); |
369 | 370 | |
371 | gjs_profiler_set_filename(profiler, "dont-conflict-with-other-test.syscap"); | |
370 | 372 | gjs_profiler_start(profiler); |
371 | 373 | |
372 | 374 | for (size_t ix = 0; ix < 100; ix++) { |
382 | 384 | } |
383 | 385 | |
384 | 386 | gjs_profiler_stop(profiler); |
387 | ||
388 | if (g_unlink("dont-conflict-with-other-test.syscap") != 0) | |
389 | g_message("Temp profiler file not deleted"); | |
385 | 390 | } |
386 | 391 | |
387 | 392 | int |