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 }