class_docstr: This object serves as the interface between a ZMQ socket passing
  Requests and Replies, and a thread or threads serving those requests.
  Received requests are received on a ZMQ socket and placed on upward_queue,
  and notify_all() is called on updward_cv.  Replies (via the Request.reply()
  method) are dispatched to their requesters via a downward queue.
  
  The Boundary wakes up the socket thread via the notify socket. This lets
  the socket thread poll for changes on the notify and request sockets, but
  allows it to receive Python objects via the downward queue.
class_docstr_tok: ["This","object","serves","as","the","interface","between","a","ZMQ","socket","passing","Requests","and","Replies",",","and","a","thread","or","threads","serving","those","requests",".","Received","requests","are","received","on","a","ZMQ","socket","and","placed","on","upward_queue",",","and","notify_all","(",")","is","called","on","updward_cv",".","Replies","(","via","the","Request.reply","(",")","method",")","are","dispatched","to","their","requesters","via","a","downward","queue",".","The","Boundary","wakes","up","the","socket","thread","via","the","notify","socket",".","This","lets","the","socket","thread","poll","for","changes","on","the","notify","and","request","sockets",",","but","allows","it","to","receive","Python","objects","via","the","downward","queue","."]
docstr: Send a message to the boundary thread via the notify socket
  
  Send a wakeup call to the boundary thread by sending arbitrary
  data to the notify socket, placing the real objects of interest
  on the downward queue.
  
  msg - message placed in the downward queue indicating the purpose
        of the wakeup call
  
  args - supplementary arguments passed to the boundary thread via
         the downward queue.
docstr_tok: ["Send","a","message","to","the","boundary","thread","via","the","notify","socket","Send","a","wakeup","call","to","the","boundary","thread","by","sending","arbitrary","data","to","the","notify","socket",",","placing","the","real","objects","of","interest","on","the","downward","queue",".","msg","-","message","placed","in","the","downward","queue","indicating","the","purpose","of","the","wakeup","call","args","-","supplementary","arguments","passed","to","the","boundary","thread","via","the","downward","queue","."]
code: def send_to_boundary_thread(self, msg, arg):
      """Send a message to the boundary thread via the notify socket
  
      Send a wakeup call to the boundary thread by sending arbitrary
      data to the notify socket, placing the real objects of interest
      on the downward queue.
  
      msg - message placed in the downward queue indicating the purpose
            of the wakeup call
  
      args - supplementary arguments passed to the boundary thread via
             the downward queue.
      """
      if not hasattr(self.threadlocal, "notify_socket"):
          self.threadlocal.notify_socket = self.zmq_context.socket(
              zmq.PUB
          )
          self.threadlocal.notify_socket.setsockopt(zmq.LINGER, 0)
          self.threadlocal.notify_socket.connect(
              cellprofiler_core.utilities.zmq.NOTIFY_SOCKET_ADDR
          )
      self.downward_queue.put((msg, arg))
      self.threadlocal.notify_socket.send(b"WAKE UP!")
  
imports: import logging
  import queue
  import threading
  import zmq
  import cellprofiler_core.utilities.zmq
  from cellprofiler_core.utilities.zmq._analysis_context import AnalysisContext
  from .communicable import Communicable
  from .communicable.reply.upstream_exit import BoundaryExited
  from .communicable.request import AnalysisRequest, Request
  from ...constants.worker import NOTIFY_STOP, NOTIFY_RUN
label_desc: Use image node_id 9 for calling the Boundary obj's underlying member method code with example usage: obj.send_to_boundary_thread(msg, arg) without return types