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 = (VmPipeSessionImpl) it.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 }
|