class_docstr: Simple fixed capacity shared memory queue of fixed size messages.
  Writing to a full queue fails, attempt to get from an empty queue blocks until data is
  available or the queue is closed.
class_docstr_tok: ["Simple","fixed","capacity","shared","memory","queue","of","fixed","size","messages",".","Writing","to","a","full","queue","fails",",","attempt","to","get","from","an","empty","queue","blocks","until","data","is","available","or","the","queue","is","closed","."]
code: def put(self, msgs: List[MSG_CLASS]) -> Optional[int]:
      assert len(msgs), "Cannot write an empty list of messages"
      if self.is_closed:
          return
      with self.lock:
          self._read_meta()
          if self.meta.size + len(msgs) > self.meta.capacity:
              raise RuntimeError("The queue is full")
          if self.meta.is_closed:
              self.is_closed = True
              return
          msgs_len = len(msgs)
          next_slot = (
              self.meta.begining + self.meta.size
          ) % self.meta.capacity
          for msg in msgs:
              self._write_msg(next_slot, msg)
              next_slot = (next_slot + 1) % self.meta.capacity
          self.meta.size += msgs_len
          self._write_meta()
          self.cv_not_empty.notify()
      return msgs_len
  
imports: from typing import List, Optional
  import os
  import threading
  from nvidia.dali._multiproc import shared_mem
  from nvidia.dali._multiproc.messages import Structure, ShmMessageDesc
  from nvidia.dali._multiproc.shared_batch import _align_up
label_desc: Use image node_id 14 for calling the ShmQueue obj's underlying member method code with example usage: obj.put(msgs) and returns: msgs_len