0

サーバーを起動し、DBus および python-dbus ライブラリを使用してサーバーと通信する Hexchat プラグインを Python で作成しようとしています。プラグインをアンロードするか、Hexchat を閉じようとするまで (すべてのプラグインをアンロードします)、すべて正常に動作します。アプリケーションがフリーズします。DBus を使用してメソッドを呼び出さないと発生しません。

問題を特定しようとしたため、最小限の例を作成しました。

サーバー.py

import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib


class EchoService(dbus.service.Object):
    def __init__(self):
        DBusGMainLoop(set_as_default=True)
        self.loop = GLib.MainLoop()

        bus_name = dbus.service.BusName(name='com.skontar.Echo', bus=dbus.SessionBus())
        super().__init__(conn=None, object_path='/com/skontar/Echo', bus_name=bus_name)

    def run(self):
        self.loop.run()

    @dbus.service.method(dbus_interface='com.skontar.Echo', in_signature='', out_signature='')
    def quit(self):
        self.loop.quit()

    @dbus.service.method(dbus_interface='com.skontar.Echo', in_signature='s', out_signature='s')
    def echo(self, text):
        print(text)
        return 'ACK'


EchoService().run()

dbus_plugin_unload_test.py

import subprocess
import time

import dbus
import hexchat

__module_name__ = 'dbus_plugin_unload_test'
__module_description__ = 'TBD'
__module_version__ = '1.0'


def get_dbus_interface():
    session_bus = dbus.SessionBus()
    dbus_object = session_bus.get_object(bus_name='com.skontar.Echo',
                                         object_path='/com/skontar/Echo')
    interface = dbus.Interface(object=dbus_object, dbus_interface='com.skontar.Echo')
    return interface


def unload(userdata):
    hexchat.prnt('Unloading {}, version {}'.format(__module_name__, __module_version__))
    global interface
    interface.quit()
    time.sleep(1)
    # raise Exception


hexchat.prnt('Loading {}, version {}'.format(__module_name__, __module_version__))
subprocess.Popen('python3 /home/skontar/Python/Examples/DBus/server.py', shell=True)
time.sleep(1)
interface = get_dbus_interface()
time.sleep(1)
interface.echo('TEST')
hexchat.hook_unload(unload)

この例では、すべてが機能します。プラグインをアンロードするか Hexchat を閉じようとすると、サーバーは終了しますが (.quit呼び出しは機能します)、Hexchat はハングします。

両方 interface.echo('TEST')をコメントアウトすると、正常にinterface.quit()アンロードされますが、プラグインは何も役に立ちません。raise Exceptionまた、アンロード コールバックの最後に、すべてが「正しく」閉じられ、何もハングしないこともわかりました。

DBus のクリーンアップを行う必要があるのではないかと考えています。または、Hexchat プラグイン システムのニュアンスが不足していますか? プラグイン システム外の通常の Python コードで同じことを試してみると、サーバーとクライアントの両方が問題なく終了します。

4

0 に答える 0