Hi Jeremy,

First of all; sorry it's taken so long time to get back to you. GH issue #171 has unfortunately taken most of my time, so this patch went on the side burner.

I've looked at your patch, and I wonder if it can be done a bit simpler. I'm open to hear your views; I might have overlooked some details.


On 10/07/2023 01:19, Jeremy Fleischman wrote:
[...snip...]
@@ -285,22 +286,24 @@ def GetFormattedStatistics(self, prefix='Connection 
statistics:\n', format_str='
      #
      def LogCallback(self, cbfnc):
          if cbfnc is not None:
+            # Remove the existing callback if there is one.
+            if self.__log_callback is not None:
+                self.LogCallback(None)
+
              self.__log_callback = cbfnc
              self.__dbuscon.add_signal_receiver(cbfnc,
                                                 signal_name='Log',
                                                 
dbus_interface='net.openvpn.v3.backends',
                                                 bus_name='net.openvpn.v3.log',
                                                 path=self.__session_path)
-            self.__session_intf.LogForward(True)
+            self.__add_LogForward_receiver()


I'm wondering if this could be made cleared. The recursion is kinda clever, but feels like it hides the purpose.

Wouldn't this code below work just as well (consider this more a concept code than proper Python code)? Here there is no recursion and no reference counting which could go wrong.

------------------------------------------------------------------------
class Session(object):
     [...]
     self.__log_forward_enabled = False

     def LogCallback(self, cbfnc):      
        if cbfnc is not None and self.__log_callback is None:
            # Log Callback function is being enabled; not
            # set before
            self.__log_callback = cbfnc
            self.__dbuscon.add_signal_receiver(cbfnc, ...)
            self.__set_log_forward(True)

        elif cbfnc is None and self.__log_callback is not None:
            # Log Callback function is being disabled; can only
            # happen because it was set
            self.__dbuscon.remove_signal_receiver(self.__log_callback,
                                                  ...)
            self.__log_callback = None
            try:
                self.__set_log_forward(False)
            except dbus.exception.DBusException:
                pass

        elif (cbfnc is not None and self.__log_callback is not None):
            # In this case, the program must first disable the
            # current LogCallback() before setting a new one.
            raise RuntimeErrpr('LogCallback() is already enabled')

        # No need to complain if unsetting an unset log callback
        # function; this will not have any behavioral impact at all.




     def __set_log_forward(self, enable):
         # This method can only be called *after* callback
         # function has been set in this object

         if not self.__log_forward_enabled and enable:
             # If log forwarding is disabled it can be enabled
             self.__log_forward_enabled = True
             self.__session_intf.LogForward(True)

         elif self.__log_forward_enabled and not enable:
             # Log forwarding can only be disabled if
             # both Log and StatusChange callbacks are unset
             if (self.__log_callback is None)
                and (self.__status_callback is None):
                 self.__log_forward_enabled = False
                 self.__session_intf.LogForward(False)

------------------------------------------------------------------------

The StatusChangeCallback() would need a similar implementation as LogCallback() too.

In regards to multi-threading; I would not expect this code to be used in a multi-threaded setup where different callbacks would be enabled/disabled on the fly in parallel. But it might be good to add this as a comment in general, that these methods are not considered thread-safe. However, since the code snippets above does not use reference counting, it should be a bit more robust as it bases the decision on the value of the callback function pointers.


Thoughts?


--
kind regards,

David Sommerseth
OpenVPN Inc




_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to