<commit_before>import dbus, dbus/lowlevel, posix, os

const maxWatches = 128

type
  MainLoop* = object
    conn: ptr DbusConnection
    watchesCount: int
    watches: array[maxWatches, ptr DbusWatch]

proc addWatch(newWatch: ptr DBusWatch, loopPtr: pointer): dbus_bool_t {.cdecl.} =
  let loop = cast[ptr MainLoop](loopPtr)
  #echo "addWatch ", dbus_watch_get_fd(watch)
  if loop.watchesCount == maxWatches:
    raise newException(ValueError, "too many watches")
  for watch in loop.watches.mitems:
    if watch == nil:
      watch = newWatch
      break
  inc loop.watchesCount
  return 1

proc removeWatch(oldWatch: ptr DBusWatch, loopPtr: pointer) {.cdecl.} =
  let loop = cast[ptr MainLoop](loopPtr)
  #echo "removeWatch"
  for watch in loop.watches.mitems:
    if watch == oldWatch:
      watch = nil
  dec loop.watchesCount

proc toggleWatch(watch: ptr DBusWatch, loopPtr: pointer) {.cdecl.} =
  discard

proc freeLoop(loopPtr: pointer) {.cdecl.} =
  discard

proc create*(cls: typedesc[MainLoop], bus: Bus): ptr MainLoop =
  ## This creates a new main loop, the returned pointer must be manually free'd
  result = create(MainLoop)
  result.conn = bus.conn
  let ok = dbus_connection_set_watch_functions(result.conn,
                                               add_function=DBusAddWatchFunction(addWatch),
                                               remove_function=DBusRemoveWatchFunction(removeWatch),
                                               toggled_function=DBusWatchToggledFunction(toggleWatch),
                                               data=result.pointer,
                                               free_data_function=freeLoop)
  assert ok != 0
  dbus_bus_add_match(result.conn, "type='signal'", nil)
  dbus_bus_add_match(result.conn, "type='method_call'", nil)

proc tick*(self: ptr MainLoop) =
  var
    fds: array[maxWatches, TPollfd]
    activeWatches: seq[ptr DbusWatch] = @[]
    nfds: int = 0
    checkedWatches = 0
<commit_msg>Fix removeWatch looping too long<commit_after>import dbus, dbus/lowlevel, posix, os

const maxWatches = 128

type
  MainLoop* = object
    conn: ptr DbusConnection
    watchesCount: int
    watches: array[maxWatches, ptr DbusWatch]

proc addWatch(newWatch: ptr DBusWatch, loopPtr: pointer): dbus_bool_t {.cdecl.} =
  let loop = cast[ptr MainLoop](loopPtr)
  #echo "addWatch ", dbus_watch_get_fd(watch)
  if loop.watchesCount == maxWatches:
    raise newException(ValueError, "too many watches")
  for watch in loop.watches.mitems:
    if watch == nil:
      watch = newWatch
      break
  inc loop.watchesCount
  return 1

proc removeWatch(oldWatch: ptr DBusWatch, loopPtr: pointer) {.cdecl.} =
  let loop = cast[ptr MainLoop](loopPtr)
  #echo "removeWatch"
  for watch in loop.watches.mitems:
    if watch == oldWatch:
      watch = nil
      break
  dec loop.watchesCount

proc toggleWatch(watch: ptr DBusWatch, loopPtr: pointer) {.cdecl.} =
  discard

proc freeLoop(loopPtr: pointer) {.cdecl.} =
  discard

proc create*(cls: typedesc[MainLoop], bus: Bus): ptr MainLoop =
  ## This creates a new main loop, the returned pointer must be manually free'd
  result = create(MainLoop)
  result.conn = bus.conn
  let ok = dbus_connection_set_watch_functions(result.conn,
                                               add_function=DBusAddWatchFunction(addWatch),
                                               remove_function=DBusRemoveWatchFunction(removeWatch),
                                               toggled_function=DBusWatchToggledFunction(toggleWatch),
                                               data=result.pointer,
                                               free_data_function=freeLoop)
  assert ok != 0
  dbus_bus_add_match(result.conn, "type='signal'", nil)
  dbus_bus_add_match(result.conn, "type='method_call'", nil)

proc tick*(self: ptr MainLoop) =
  var
    fds: array[maxWatches, TPollfd]
    activeWatches: seq[ptr DbusWatch] = @[]
    nfds: int = 0
    checkedWatches = 0

{'fraction_non_alphanumeric': 0.09111502642839164, 'fraction_numerical': 0.003523785552479235, 'mean_word_length': 2.6325411334552102, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '564508', 'n_tokens_mistral': 1220, 'n_tokens_neox': 1187, 'n_words': 307}