001 /**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020 package org.apache.james.jspf.impl; 021 022 import org.apache.james.jspf.core.DNSRequest; 023 import org.apache.james.jspf.core.DNSService; 024 import org.apache.james.jspf.core.exceptions.TimeoutException; 025 import org.apache.james.jspf.executor.DNSAsynchLookupService; 026 import org.apache.james.jspf.executor.IResponseImpl; 027 import org.apache.james.jspf.executor.IResponseQueue; 028 029 import java.util.LinkedList; 030 031 /** 032 * Wrap a DNSService an execute the calls asynch in a new Thread 033 */ 034 public class DNSServiceAsynchSimulator implements Runnable, DNSAsynchLookupService { 035 036 private DNSService dnsService; 037 private Thread worker; 038 private LinkedList<Request> queue; 039 private int waitingThreads = 0; 040 private boolean multiThread; 041 042 private static final class Request { 043 private final DNSRequest value; 044 private final Object id; 045 private final IResponseQueue responseQueue; 046 public Request(DNSRequest value, Object id, IResponseQueue responseQueue) { 047 this.value = value; 048 this.id = id; 049 this.responseQueue = responseQueue; 050 } 051 public DNSRequest getValue() { 052 return value; 053 } 054 public Object getId() { 055 return id; 056 } 057 public IResponseQueue getResponseQueue() { 058 return responseQueue; 059 } 060 061 } 062 063 public DNSServiceAsynchSimulator(DNSService service, boolean multiThread) { 064 this.dnsService = service; 065 this.multiThread = multiThread; 066 067 this.queue = new LinkedList<Request>(); 068 this.worker = new Thread(this); 069 this.worker.setDaemon(true); 070 this.worker.setName("DNSServiceAsynchSimulator"); 071 this.worker.start(); 072 073 } 074 075 /** 076 * @see org.apache.james.jspf.executor.DNSAsynchLookupService#getRecordsAsynch(org.apache.james.jspf.core.DNSRequest, int, org.apache.james.jspf.executor.IResponseQueue) 077 */ 078 public void getRecordsAsynch(DNSRequest request, int id, 079 final IResponseQueue responsePool) { 080 081 synchronized (queue) { 082 queue.addLast(new Request(request, new Integer(id), responsePool)); 083 queue.notify(); 084 } 085 086 } 087 088 /** 089 * Run the async dns call in a new thread 090 */ 091 public void run() { 092 while (true) { 093 Request req; 094 synchronized (queue) { 095 if ( (queue.size() - waitingThreads <= 0) ) { 096 try { 097 waitingThreads++; queue.wait(); 098 } catch (InterruptedException e) { 099 Thread.interrupted(); 100 } 101 waitingThreads--; 102 } 103 req = (Request) queue.removeFirst(); 104 } 105 106 Runnable runnable = new Runnable() { 107 108 private Request req; 109 110 public void run() { 111 IResponseImpl response; 112 try { 113 response = new IResponseImpl(req.getId(), dnsService.getRecords(req.getValue())); 114 } catch (TimeoutException e) { 115 response = new IResponseImpl(req.getId(), e); 116 } 117 118 req.getResponseQueue().insertResponse(response); 119 } 120 121 public Runnable setRequest(Request req) { 122 this.req = req; 123 return this; 124 } 125 126 }.setRequest(req); 127 128 if (multiThread) { 129 new Thread(runnable).start(); 130 } else { 131 runnable.run(); 132 } 133 } 134 } 135 136 }