1 /* 2 * Created on 9 Aug 2006 3 * Created by Paul Gardner 4 * Copyright (C) Azureus Software, Inc, All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 18 */ 19 20 package org.gudy.azureus2.core3.util; 21 22 public class 23 FrequencyLimitedDispatcher 24 { 25 private AERunnable target; 26 private long min_millis; 27 28 private long last_run; 29 private DelayedEvent delay_event; 30 31 public FrequencyLimitedDispatcher( AERunnable _target, int _min_frequency_millis )32 FrequencyLimitedDispatcher( 33 AERunnable _target, 34 int _min_frequency_millis ) 35 { 36 target = _target; 37 min_millis = _min_frequency_millis; 38 } 39 40 public void setSingleThreaded()41 setSingleThreaded() 42 { 43 final AERunnable old_target = target; 44 45 target = 46 new AERunnable() 47 { 48 private boolean running; 49 private boolean pending; 50 51 public void 52 runSupport() 53 { 54 synchronized( this ){ 55 56 if ( running ){ 57 58 pending = true; 59 60 return; 61 } 62 63 running = true; 64 } 65 66 try{ 67 old_target.runSupport(); 68 69 }finally{ 70 71 boolean was_pending; 72 73 synchronized( this ){ 74 75 running = false; 76 77 was_pending = pending; 78 79 pending = false; 80 } 81 82 if ( was_pending ){ 83 84 dispatch(); 85 } 86 } 87 } 88 }; 89 } 90 91 public void dispatch()92 dispatch() 93 { 94 long now = SystemTime.getMonotonousTime(); 95 96 boolean run_it = false; 97 98 synchronized( this ){ 99 100 if ( delay_event == null ){ 101 102 long delay = min_millis - (now - last_run ); 103 104 if ( now < last_run || delay <= 0 ){ 105 106 last_run = now; 107 108 run_it = true; 109 110 }else{ 111 112 // run too recently 113 114 delay_event = 115 new DelayedEvent( 116 "FreqLimDisp", 117 delay, 118 new AERunnable() 119 { 120 public void 121 runSupport() 122 { 123 long now = SystemTime.getMonotonousTime(); 124 125 synchronized( FrequencyLimitedDispatcher.this ){ 126 127 last_run = now; 128 129 delay_event = null; 130 } 131 132 target.run(); 133 } 134 }); 135 } 136 } 137 } 138 139 if ( run_it ){ 140 141 target.run(); 142 } 143 } 144 } 145