/** * Expires this <tt>Conference</tt>, its <tt>Content</tt>s and their respective <tt>Channel</tt>s. * Releases the resources acquired by this instance throughout its life time and prepares it to be * garbage collected. */ public void expire() { synchronized (this) { if (expired) return; else expired = true; } EventAdmin eventAdmin = videobridge.getEventAdmin(); if (eventAdmin != null) eventAdmin.sendEvent(EventFactory.conferenceExpired(this)); setRecording(false); if (recorderEventHandler != null) { recorderEventHandler.close(); recorderEventHandler = null; } Videobridge videobridge = getVideobridge(); try { videobridge.expireConference(this); } finally { // Expire the Contents of this Conference. for (Content content : getContents()) { try { content.expire(); } catch (Throwable t) { logger.warn( "Failed to expire content " + content.getName() + " of conference " + getID() + "!", t); if (t instanceof InterruptedException) Thread.currentThread().interrupt(); else if (t instanceof ThreadDeath) throw (ThreadDeath) t; } } // Close the transportManagers of this Conference. Normally, there // will be no TransportManager left to close at this point because // all Channels have expired and the last Channel to be removed from // a TransportManager closes the TransportManager. However, a // Channel may have expired before it has learned of its // TransportManager and then the TransportManager will not close. closeTransportManagers(); if (logger.isInfoEnabled()) { logger.info( "Expired conference " + getID() + ". " + videobridge.getConferenceCountString()); } } }
/** * Gets a <tt>Content</tt> of this <tt>Conference</tt> which has a specific name. If a * <tt>Content</tt> of this <tt>Conference</tt> with the specified <tt>name</tt> does not exist at * the time the method is invoked, the method initializes a new <tt>Content</tt> instance with the * specified <tt>name</tt> and adds it to the list of <tt>Content</tt>s of this * <tt>Conference</tt>. * * @param name the name of the <tt>Content</tt> which is to be returned * @return a <tt>Content</tt> of this <tt>Conference</tt> which has the specified <tt>name</tt> */ public Content getOrCreateContent(String name) { Content content; synchronized (contents) { for (Content aContent : contents) { if (aContent.getName().equals(name)) { aContent.touch(); // It seems the content is still active. return aContent; } } content = new Content(this, name); if (isRecording()) { content.setRecording(true, getRecordingPath()); } contents.add(content); } if (logger.isInfoEnabled()) { /* * The method Videobridge.getChannelCount() should better be * executed outside synchronized blocks in order to reduce the risks * of causing deadlocks. */ Videobridge videobridge = getVideobridge(); logger.info( "Created content " + name + " of conference " + getID() + ". " + videobridge.getConferenceCountString()); } return content; }