1

Here are two little scripts that show how I am using kevents right now, and reproduce my problem.

kqtest.py:

import socket
import select
import threading

server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
server_sock.bind(('localhost', 8080))
server_sock.listen(1)

client, addr = server_sock.accept()

kev = select.kevent(client)
kq = select.kqueue()
kq.control([kev], 0, 0)

while True:
    events = kq.control([], 1, 1)
    if events:
        event = events[0]
        if event.ident == kev.ident:
            print("ready to read client %s:%s" % addr)
            print(client.recv(1024))

kqtesttrigger.py:

import socket

trigger = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
trigger.connect(('localhost', 8080))
trigger.send(b"THIS IS THE TRIGGER!!! LA-DEE-DAAAAA-DEE-DAAA!!!")

Output of kqtest once I trigger it:

ready to read client 127.0.0.1:63868
b'THIS IS THE TRIGGER!!! LA-DEE-DAAAAA-DEE-DAAA!!!'
ready to read client 127.0.0.1:63868
b''
ready to read client 127.0.0.1:63868
b''
ready to read client 127.0.0.1:63868
b''
...this repeats until I kill it

What I want is for the kevent to only be triggered when data has been added to the socket. Do I need to remove the kevent from the kqueue and re add it?

Broseph
  • 1,655
  • 1
  • 18
  • 38

1 Answers1

0

I found after some experimenting that, once the trigger socket was closed, it caused kq.control to return immediately and have KQ_EV_EOF set in the flags attribute of the returned event. I just need to check the flag each time the event is returned to make sure it doesn't have KV_EQ_EOF set!

Broseph
  • 1,655
  • 1
  • 18
  • 38