/*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This source code is provided to illustrate the usage of a given feature
* or technique and has been deliberately simplified. Additional steps
* required for a production-quality application, such as security checks,
* input validation and proper error handling, might not be present in
* this sample code.
*/
/**
* Simple Java "server" using the Poller class
* to multiplex on incoming connections. Note
* that handoff of events, via linked Q is not
* actually be a performance booster here, since
* the processing of events is cheaper than
* the overhead in scheduling/executing them.
* Although this demo does allow for concurrency
* in handling connections, it uses a rather
* primitive "gang scheduling" policy to keep
* the code simpler.
*/
public class PollingServer
{
/**
* This synchronization object protects access to certain
* data (bytesRead,eventsToProcess) by concurrent Consumer threads.
*/
private static int bytesToRead;
int bytes;
int serverFd;
int totalConn=0;
int connects=0;
try {
/*
* Create the Poller object Mux, allow for up to MAXCONN
* sockets/filedescriptors to be polled.
*/
totalConn + " client connections");
/*
* Start the consumer threads to read data.
*/
for (int consumerThread = 0;
}
/*
* Take connections, read Data
*/
int numEvents=0;
while ( bytesRead < bytesToRead ) {
int loopWaits=0;
while (eventsToProcess > 0) {
synchronized (eventSync) {
loopWaits++;
if (eventsToProcess <= 0) break;
}
}
if (loopWaits > 1)
" events " + numEvents +
" bytes read : " + bytesRead );
/*
* Wait for events
*/
synchronized (eventSync) {
}
/*
* Process all the events we got from Mux.waitMultiple
*/
int cnt = 0;
/*
* New connection coming in on the ServerSocket
* Add the socket to the Mux, keep track of mapping
* the fdval returned by Mux.add to the connection.
*/
synchronized(eventSync) {
eventsToProcess--; // just processed this one!
}
connects++;
} else {
/*
* We've got data from this client connection.
* Put it on the queue for the consumer threads to process.
*/
}
} else {
}
cnt++;
}
}
// Tell the client it can now go away
byte[] buff = new byte[BYTESPEROP];
// Tell the cunsumer threads they can exit.
}
}
/*
* main ... just check if a concurrency was specified
*/
{
int concurrency;
else
}
/*
* This class is for handling the Client data.
* The PollingServer spawns off a number of these based upon
* the number of CPUs (or concurrency argument).
* Each just loops grabbing events off the queue and
* processing them.
*/
private int threadNumber;
public void run() {
byte[] buff = new byte[BYTESPEROP];
int bytes = 0;
while (bytesRead < bytesToRead) {
try {
/*
* We have to map the fd value returned from waitMultiple
* to the actual input stream associated with that fd.
* Take a look at how the Mux.add() was done to see how
* we stored that.
*/
if (bytes > 0) {
/*
* Any real server would do some synchronized and some
* unsynchronized work on behalf of the client, and
* most likely send some data back...but this is a
* gross oversimplification.
*/
synchronized(eventSync) {
if (eventsToProcess <= 0) {
}
}
}
}
}
}
}