docs: public boolean checkIfEJBWorkAllowed(EJBModuleMetaDataImpl module) {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
  
          // F743-15941 - By default, this flag will be false for compatibility.
          // For performance, this flag will be reset after the application is
          // fully started, so we use double-checked locking with a volatile.
          // For late add modules, this flag will be reset back to true by the
          // starting thread before any beans from that module are exposed.
          if (!ivCurrentlyBlockingWork) {
              if (isTraceOn && tc.isDebugEnabled())
                  Tr.debug(tc, "checkIfEJBWorkAllowed: " + module.getJ2EEName() + ": not blocking work");
              return true;
          }
  
          EJBModuleMetaDataImpl moduleBeingAddedLate;
          synchronized (this) {
              if (!ivCurrentlyBlockingWork) {
                  // The application has fully started, so allow this and all future
                  // work requests.
                  if (isTraceOn && tc.isDebugEnabled())
                      Tr.debug(tc, "checkIfEJBWorkAllowed: " + module.getJ2EEName() + ": not blocking work");
                  return true;
              }
  
              if (ivStartupThread == Thread.currentThread()) {
                  // The application is in the process of being started, and the
                  // caller is the startup thread. Allow this work request only
                  // until the application is fully started.
                  if (isTraceOn && tc.isDebugEnabled())
                      Tr.debug(tc, "checkIfEJBWorkAllowed: " + module.getJ2EEName() + ": allowing startup thread");
                  return false;
              }
  
              moduleBeingAddedLate = ivModuleBeingAddedLate;
              if (moduleBeingAddedLate != null && moduleBeingAddedLate != module) {
                  // startupThread is not null and ivModuleBeingAddedLate is not
                  // null, which means a module is being added to a started
                  // application. Since the work request is for a module that is
                  // already part of the started application, allow this and all
                  // future work requests.
                  if (isTraceOn && tc.isDebugEnabled())
                      Tr.debug(tc, "checkIfEJBWorkAllowed: " + module.getJ2EEName() + ": allowing non-late-add module");
                  return true;
              }
  
              // At this point, one of two scenarios is occurring:
              // 1. The application is being started, but work has been requested on
              // some thread other than the startup thread.
              // 2. A module is being added to a started application, but work has
              // been requested for that module on some thread other than the
              // module startup thread.
              //
              // F743-15941 - In either case, wait for the application or module to
              // finish starting either successfully or unsuccessfully.
              long begin = System.nanoTime();
              long end = begin + TimeUnit.MILLISECONDS.toNanos(ContainerProperties.BlockWorkUntilAppStartedWaitTime);
  
              if (isTraceOn && tc.isDebugEnabled())
                  Tr.debug(tc, "checkIfEJBWorkAllowed: " + module.getJ2EEName() + ": waiting for application to start");
  
              // Continue waiting for either the application or module to finish
              // starting. If we were waiting for a late-add module (i.e.,
              // moduleBeingAddedLate != null), then stop waiting if a different
              // module is now being started.
              while (ivCurrentlyBlockingWork && (moduleBeingAddedLate == null || moduleBeingAddedLate == ivModuleBeingAddedLate)) {
                  try {
                      long waitTime = end - System.nanoTime();
                      if (waitTime <= 0) {
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "checkIfEJBWorkAllowed: wait timed out");
  
                          // The application or module did not finish starting
                          // in the allotted time. Note that this will occur if
                          // the startup thread (e.g., servlet context listener,
                          // singleton startup, or legacy startup bean) attempted
                          // to wait for asynchronous work (e.g., fire-and-return
                          // async, MDB, timer) to be delivered to itself.
  
                          if (moduleBeingAddedLate != null) {
                              throw new ApplicationNotStartedException("module " + module.getName() + " in application " + ivName
                                      + " has not finished startup processing");
                          }
  
                          throw new ApplicationNotStartedException("application " + ivName + " has not finished startup processing");
                      }
  
                      // Wait until notified by unblockThreadsWaitingForStart.
                      TimeUnit.NANOSECONDS.timedWait(this, waitTime);
                  } catch (InterruptedException ex) {
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "checkIfEJBWorkAllowed: wait interrupted");
                      FFDCFilter.processException(ex, CLASS_NAME + ".checkIfEJBWorkAllowed", "360", this);
                      Thread.currentThread().interrupt();
                  }
              }
          }
  
          // The application or module is no longer starting, but now we need
          // to check whether the start was successful.
  
          // EJBModuleMetaDataImpl.ivStopping isn't volatile, but the startup
          // thread will also synchronize on this object via cleanUp.
          if (moduleBeingAddedLate != null && moduleBeingAddedLate.ivStopping) {
              // The late-add module failed to start.
              if (isTraceOn && tc.isDebugEnabled())
                  Tr.debug(tc, "checkIfEJBWorkAllowed: module failed to start");
              throw new EJBStoppedException("module " + module.getName() + " in application " + ivName + " failed to start");
          }
  
          if (ivStopping) {
              // The application failed to start.
              if (isTraceOn && tc.isDebugEnabled())
                  Tr.debug(tc, "checkIfEJBWorkAllowed: application failed to start");
              throw new EJBStoppedException("application " + ivName + " failed to start");
          }
  
          if (isTraceOn && tc.isDebugEnabled())
              Tr.debug(tc, "checkIfEJBWorkAllowed: application started");
          return true;
      }