Travis Griggs Travis Griggs - 1 year ago 64
Linux Question

io_add_watch callback only fires once?

I have a named pipe which I want to react to when data is available. I am doing this in the context of dbus. For setup, I have the following:

mainloop = glib.MainLoop()
fifo ='_notify', os.O_RDWR)
glib.io_add_watch(fifo, glib.IO_IN, notifyLoop, service)
except KeyboardInterrupt:

So in the 2nd and 3rd lines, I'm opening the named pipe, and adding a watch to it. My

def notifyLoop(fifo, cb_cond, service):
dataStream = service.characteristics[0]
all =, 2048)
print('all', all, 'cb_cond', cb_cond)
payload, all = all[:20], all[20:]
while payload:
newValue = {'Value': [dbus.Byte(x) for x in payload]}
dataStream.PropertiesChanged(GATT_CHRC_IFACE, newValue, [])
payload, all = all[:20], all[20:]

Basically, read everything in the pipe, and then break into chunks of size 20 and signal those. The problem is that the callback only fires once, the first time. The first time, I see the print, but when I write more data to the pipe from another program, nothing happens. Am I misunderstanding the way

Here's the code I used to write two separate things to the named pipe:

user@machine:/Directory# python3
Python 3.4.2 (default, Oct 8 2014, 14:38:51)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> fifo ='_notify', os.O_RDWR)
>>> os.write(fifo, b'\xDE\xAD')
>>> os.write(fifo, b'\xBE\xEF')

After the first write, I see

all b'\xde\xad' cb_cond <flags G_IO_IN of type GIOCondition>

where the dbus program is running. But nothing for the second write.

Answer Source

Through trial and error, I determined I did indeed need to execute glib.io_add_watch() at the end of each callback occurrence to keep rearming it.