VmPipeIdleStatusChecker.java
001 /*
002  *
003  * Licensed to the Apache Software Foundation (ASF) under one
004  * or more contributor license agreements.  See the NOTICE file
005  * distributed with this work for additional information
006  * regarding copyright ownership.  The ASF licenses this file
007  * to you under the Apache License, Version 2.0 (the
008  * "License"); you may not use this file except in compliance
009  * with the License.  You may obtain a copy of the License at
010  *
011  *   http://www.apache.org/licenses/LICENSE-2.0
012  *
013  * Unless required by applicable law or agreed to in writing,
014  * software distributed under the License is distributed on an
015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016  * KIND, either express or implied.  See the License for the
017  * specific language governing permissions and limitations
018  * under the License.
019  *
020  */
021 package org.apache.mina.transport.vmpipe.support;
022 
023 import org.apache.mina.common.IdleStatus;
024 
025 import java.util.HashMap;
026 import java.util.IdentityHashMap;
027 import java.util.Iterator;
028 import java.util.Map;
029 
030 /**
031  * This file is a patch to override MINA, because of the IdentityHashMap bug. Workaround to be supplied in MINA 1.0.7.
032  * This patched file will be removed once upgraded onto a newer MINA.
033  *
034  * Dectects idle sessions and fires <tt>sessionIdle</tt> events to them.
035  *
036  @author The Apache Directory Project (mina-dev@directory.apache.org)
037  */
038 public class VmPipeIdleStatusChecker
039 {
040     private static final VmPipeIdleStatusChecker INSTANCE = new VmPipeIdleStatusChecker();
041 
042     public static VmPipeIdleStatusChecker getInstance()
043     {
044         return INSTANCE;
045     }
046 
047     private final Map sessions = new HashMap()// will use as a set
048 
049     private final Worker worker = new Worker();
050 
051     private VmPipeIdleStatusChecker()
052     {
053         worker.start();
054     }
055 
056     public void addSession(VmPipeSessionImpl session)
057     {
058         synchronized (sessions)
059         {
060             sessions.put(session, session);
061         }
062     }
063 
064     private class Worker extends Thread
065     {
066         private Worker()
067         {
068             super("VmPipeIdleStatusChecker");
069             setDaemon(true);
070         }
071 
072         public void run()
073         {
074             for (;;)
075             {
076                 try
077                 {
078                     Thread.sleep(1000);
079                 }
080                 catch (InterruptedException e)
081                 { }
082 
083                 long currentTime = System.currentTimeMillis();
084 
085                 synchronized (sessions)
086                 {
087                     Iterator it = sessions.keySet().iterator();
088                     while (it.hasNext())
089                     {
090                         VmPipeSessionImpl session = (VmPipeSessionImplit.next();
091                         if (!session.isConnected())
092                         {
093                             it.remove();
094                         }
095                         else
096                         {
097                             notifyIdleSession(session, currentTime);
098                         }
099                     }
100                 }
101             }
102         }
103     }
104 
105     private void notifyIdleSession(VmPipeSessionImpl session, long currentTime)
106     {
107         notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE), IdleStatus.BOTH_IDLE,
108             Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
109         notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.READER_IDLE), IdleStatus.READER_IDLE,
110             Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
111         notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE), IdleStatus.WRITER_IDLE,
112             Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
113     }
114 
115     private void notifyIdleSession0(VmPipeSessionImpl session, long currentTime, long idleTime, IdleStatus status,
116         long lastIoTime)
117     {
118         if ((idleTime > 0&& (lastIoTime != 0&& ((currentTime - lastIoTime>= idleTime))
119         {
120             session.increaseIdleCount(status);
121             session.getFilterChain().fireSessionIdle(session, status);
122         }
123     }
124 
125 }