Skip to content

Commit 3e3d140

Browse files
committed
fix: Remove GClosure implementation details and use hardcoded sizeof
1 parent fdcbf62 commit 3e3d140

File tree

2 files changed

+16
-44
lines changed

2 files changed

+16
-44
lines changed

src/FFI.php

+14-42
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,18 @@ public static function shutDown(): void
178178
self::vips()->vips_shutdown();
179179
}
180180

181+
public static function newGClosure(): \FFI\CData
182+
{
183+
// GClosure measures 32-bit with the first few fields until marshal
184+
// Marshal is a function pointer, thus platform-dependant.
185+
// Data is a pointer, thus platform-dependant.
186+
// Notifiers is an array-pointer, thus platform-dependant.
187+
// All in all it's basically 4 (bytes) + 3 * POINTER_SIZE
188+
// However, gobject wants 8 (bytes) + 3 * POINTER_SIZE.
189+
// I'm not sure where that extra byte comes from. Padding on 64-bit machines?
190+
return self::gobject()->g_closure_new_simple(8 + 3 * PHP_INT_SIZE, null);
191+
}
192+
181193
private static function libraryName(string $name, int $abi): string
182194
{
183195
switch (PHP_OS_FAMILY) {
@@ -433,7 +445,7 @@ private static function init(): void
433445
434446
const char* g_param_spec_get_blurb (GParamSpec* psp);
435447
436-
typedef struct _GClosure GClosure;
448+
typedef void *GClosure;
437449
typedef void (*marshaler)(
438450
struct GClosure* closure,
439451
GValue* return_value,
@@ -442,47 +454,7 @@ private static function init(): void
442454
void* invocation_hint,
443455
void* marshal_data
444456
);
445-
446-
typedef struct _GClosureNotifyData GClosureNotifyData;
447-
struct _GClosureNotifyData
448-
{
449-
void* data;
450-
GClosureNotify notify;
451-
};
452-
struct _GClosure
453-
{
454-
/*< private >*/
455-
int ref_count : 15; /* (atomic) */
456-
/* meta_marshal is not used anymore but must be zero for historical reasons
457-
as it was exposed in the G_CLOSURE_N_NOTIFIERS macro */
458-
int meta_marshal_nouse : 1; /* (atomic) */
459-
int n_guards : 1; /* (atomic) */
460-
int n_fnotifiers : 2; /* finalization notifiers (atomic) */
461-
int n_inotifiers : 8; /* invalidation notifiers (atomic) */
462-
int in_inotify : 1; /* (atomic) */
463-
int floating : 1; /* (atomic) */
464-
/*< protected >*/
465-
int derivative_flag : 1; /* (atomic) */
466-
/*< public >*/
467-
int in_marshal : 1; /* (atomic) */
468-
int is_invalid : 1; /* (atomic) */
469-
470-
/*< private >*/ marshaler marshal;
471-
/*< protected >*/ void* data;
472-
473-
/*< private >*/ GClosureNotifyData *notifiers;
474-
475-
/* invariants/constraints:
476-
* - ->marshal and ->data are _invalid_ as soon as ->is_invalid==TRUE
477-
* - invocation of all inotifiers occurs prior to fnotifiers
478-
* - order of inotifiers is random
479-
* inotifiers may _not_ free/invalidate parameter values (e.g. ->data)
480-
* - order of fnotifiers is random
481-
* - each notifier may only be removed before or during its invocation
482-
* - reference counting may only happen prior to fnotify invocation
483-
* (in that sense, fnotifiers are really finalization handlers)
484-
*/
485-
};
457+
void g_closure_set_marshal(GClosure* closure, marshaler marshal);
486458
long g_signal_connect_closure(GObject* object, const char* detailed_signal, GClosure *closure, bool after);
487459
GClosure* g_closure_new_simple (int sizeof_closure, void* data);
488460
EOS;

src/GObject.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ public function signalConnect(string $name, callable $callback): void
109109
throw new Exception("unsupported signal $name");
110110
}
111111

112-
$gc = FFI::gobject()->g_closure_new_simple(\FFI::sizeof(FFI::ctypes('GClosure')), null);
113-
$gc->marshal = $marshaler;
112+
$gc = FFI::newGClosure();
113+
FFI::gobject()->g_closure_set_marshal($gc, $marshaler);
114114
FFI::gobject()->g_signal_connect_closure($this->pointer, $name, $gc, 0);
115115
}
116116

0 commit comments

Comments
 (0)