Skip to content

FFI: A state is kept somewhere between two HTTP requst #18621

Closed as not planned
Closed as not planned
@lyrixx

Description

@lyrixx

Description

The following code:

<?php

class LibNotifyDriver
{
    private static FFI $ffi;

    public function send(): bool
    {
        $this->initialize();
        $notification = self::$ffi->notify_notification_new(
            'a title',
            'a body',
            null,
        );
        $value = self::$ffi->notify_notification_show($notification, null);
        self::$ffi->g_object_unref($notification);

        return $value;
    }

    private static function initialize(): void
    {
        if (isset(self::$ffi)) {
            return;
        }

        $header = <<<'C'
            typedef bool gboolean;
            typedef void* gpointer;
            typedef struct _NotifyNotification NotifyNotification;
            typedef struct _GTypeInstanceError GError;

            gboolean notify_init(const char *app_name);
            gboolean notify_is_initted (void);
            void notify_uninit (void);
            NotifyNotification *notify_notification_new(const char *summary, const char *body, const char *icon);
            gboolean notify_notification_show (NotifyNotification *notification, GError **error);
            void g_object_unref (gpointer object);
            C;

        $ffi = FFI::cdef($header, 'libnotify.so.4');

        if (!$ffi) {
            throw new RuntimeException('Unable to load libnotify');
        }

        self::$ffi = $ffi;

        if (!self::$ffi->notify_init('app')) {
            throw new RuntimeException('Unable to initialize libnotify');
        }

        if (!self::$ffi->notify_is_initted()) {
            throw new RuntimeException('Libnotify has not been initialized');
        }
    }
}

$driver = new LibNotifyDriver();
$driver->send();

Resulted in this output:

>…ire/dev/github.com/jolicode/JoliNotif(ffi) php -S 127.0.0.1:9999 test.php 
[Thu May 22 15:14:12 2025] PHP 8.4.7 Development Server (http://127.0.0.1:9999) started
[Thu May 22 15:14:14 2025] 127.0.0.1:42474 Accepted
[Thu May 22 15:14:14 2025] 127.0.0.1:42474 Closing
[Thu May 22 15:14:15 2025] 127.0.0.1:42480 Accepted

(process:2370852): GLib-GObject-WARNING **: 15:14:15.844: cannot register existing type 'NotifyNotification'

(process:2370852): GLib-CRITICAL **: 15:14:15.844: g_once_init_leave: assertion 'result != 0' failed

(process:2370852): GLib-GObject-CRITICAL **: 15:14:15.844: g_object_new_valist: assertion 'G_TYPE_IS_OBJECT (object_type)' failed

(process:2370852): libnotify-CRITICAL **: 15:14:15.844: notify_notification_show: assertion 'notification != NULL' failed

(process:2370852): GLib-GObject-CRITICAL **: 15:14:15.844: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
[Thu May 22 15:14:15 2025] 127.0.0.1:42480 Closing

But I expected this output instead:

>…ire/dev/github.com/jolicode/JoliNotif(ffi) php -S 127.0.0.1:9999 test.php 
[Thu May 22 15:14:12 2025] PHP 8.4.7 Development Server (http://127.0.0.1:9999) started
[Thu May 22 15:14:14 2025] 127.0.0.1:42474 Accepted
[Thu May 22 15:14:14 2025] 127.0.0.1:42474 Closing
[Thu May 22 15:14:15 2025] 127.0.0.1:42480 Accepted
[Thu May 22 15:14:15 2025] 127.0.0.1:42480 Closing

We found this issue via jolicode/JoliNotif#120

In cli, we had some troubles, so I refactored the code to allow only once instance. But with a web SAPI, it does not work. On the very first request, it works, but on the second one it does not.

I tested with the cli-server SAPI, and FPM SAPI

PHP Version

PHP 8.4.7 (cli) (built: May  9 2025 06:54:08) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.7, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.7, Copyright (c), by Zend Technologies
    with blackfire v1.92.32~linux-x64-non_zts84, https://blackfire.io, by Blackfire

Operating System

Ubuntu 22.04.5 LTS

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions