
io.jsync.net.impl.HandlerManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsync.io Show documentation
Show all versions of jsync.io Show documentation
jsync.io is a non-blocking, event-driven networking framework for Java
/*
* Copyright (c) 2011-2013 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.jsync.net.impl;
import io.jsync.Handler;
import io.jsync.impl.DefaultContext;
import io.jsync.logging.Logger;
import io.jsync.logging.impl.LoggerFactory;
import io.netty.channel.EventLoop;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author Tim Fox
*/
public class HandlerManager {
@SuppressWarnings("unused")
private static final Logger log = LoggerFactory.getLogger(HandlerManager.class);
private final AsyncEventLoopGroup availableWorkers;
private final ConcurrentMap> handlerMap = new ConcurrentHashMap<>();
// We maintain a separate handler count so we can implement hasHandlers() efficiently
private volatile int handlerCount;
public HandlerManager(AsyncEventLoopGroup availableWorkers) {
this.availableWorkers = availableWorkers;
}
public boolean hasHandlers() {
return handlerCount != 0;
}
public HandlerHolder chooseHandler(EventLoop worker) {
Handlers handlers = handlerMap.get(worker);
return handlers == null ? null : handlers.chooseHandler();
}
public void addHandler(Handler handler, DefaultContext context) {
EventLoop worker = context.getEventLoop();
availableWorkers.addWorker(worker);
Handlers handlers = new Handlers();
Handlers prev = handlerMap.putIfAbsent(worker, handlers);
if (prev != null) {
handlers = prev;
}
handlers.addHandler(new HandlerHolder<>(context, handler));
handlerCount++;
}
public void removeHandler(Handler handler, DefaultContext context) {
EventLoop worker = context.getEventLoop();
Handlers handlers = handlerMap.get(worker);
if (!handlers.removeHandler(new HandlerHolder<>(context, handler))) {
throw new IllegalStateException("Can't find handler");
}
if (handlers.isEmpty()) {
handlerMap.remove(worker);
}
handlerCount--;
//Available workers does it's own reference counting -since workers can be shared across different Handlers
availableWorkers.removeWorker(worker);
}
private static final class Handlers {
private final List> list = new CopyOnWriteArrayList<>();
private int pos;
HandlerHolder chooseHandler() {
HandlerHolder handler = list.get(pos);
pos++;
checkPos();
return handler;
}
void addHandler(HandlerHolder handler) {
list.add(handler);
}
boolean removeHandler(HandlerHolder handler) {
if (list.remove(handler)) {
checkPos();
return true;
} else {
return false;
}
}
boolean isEmpty() {
return list.isEmpty();
}
void checkPos() {
if (pos == list.size()) {
pos = 0;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy