use of io.undertow.connector.ByteBufferPool in project undertow by undertow-io.
the class UndertowContainerProvider method getDefaultContainer.
static ServerWebSocketContainer getDefaultContainer() {
if (defaultContainerDisabled) {
return null;
}
if (defaultContainer != null) {
return defaultContainer;
}
synchronized (UndertowContainerProvider.class) {
if (defaultContainer == null) {
// this is not great, as we have no way to control the lifecycle
// but there is not much we can do
// todo: what options should we use here?
ByteBufferPool buffers = new DefaultByteBufferPool(directBuffers, 1024, 100, 12);
defaultContainer = new ServerWebSocketContainer(defaultIntrospector, UndertowContainerProvider.class.getClassLoader(), new Supplier<XnioWorker>() {
volatile XnioWorker worker;
@Override
public XnioWorker get() {
if (worker == null) {
synchronized (this) {
if (worker == null) {
try {
worker = Xnio.getInstance().createWorker(OptionMap.create(Options.THREAD_DAEMON, true));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
return worker;
}
}, buffers, Collections.EMPTY_LIST, !invokeInIoThread);
}
return defaultContainer;
}
}
use of io.undertow.connector.ByteBufferPool in project undertow by undertow-io.
the class Bootstrap method handleDeployment.
@Override
public void handleDeployment(DeploymentInfo deploymentInfo, ServletContext servletContext) {
WebSocketDeploymentInfo info = (WebSocketDeploymentInfo) deploymentInfo.getServletContextAttributes().get(WebSocketDeploymentInfo.ATTRIBUTE_NAME);
if (info == null) {
return;
}
Supplier<XnioWorker> worker = info.getWorker();
ByteBufferPool buffers = info.getBuffers();
if (buffers == null) {
ServerWebSocketContainer defaultContainer = UndertowContainerProvider.getDefaultContainer();
if (defaultContainer == null) {
throw JsrWebSocketLogger.ROOT_LOGGER.bufferPoolWasNullAndNoDefault();
}
JsrWebSocketLogger.ROOT_LOGGER.bufferPoolWasNull();
buffers = defaultContainer.getBufferPool();
}
final List<ThreadSetupHandler> setup = new ArrayList<>();
setup.add(new ContextClassLoaderSetupAction(deploymentInfo.getClassLoader()));
setup.addAll(deploymentInfo.getThreadSetupActions());
InetSocketAddress bind = null;
if (info.getClientBindAddress() != null) {
bind = new InetSocketAddress(info.getClientBindAddress(), 0);
}
List<Extension> extensions = new ArrayList<>();
for (ExtensionHandshake e : info.getExtensions()) {
extensions.add(new ExtensionImpl(e.getName(), Collections.emptyList()));
}
ServerWebSocketContainer container = new ServerWebSocketContainer(deploymentInfo.getClassIntrospecter(), servletContext.getClassLoader(), worker, buffers, setup, info.isDispatchToWorkerThread(), bind, info.getReconnectHandler(), extensions);
try {
for (Class<?> annotation : info.getAnnotatedEndpoints()) {
container.addEndpoint(annotation);
}
for (ServerEndpointConfig programatic : info.getProgramaticEndpoints()) {
container.addEndpoint(programatic);
}
} catch (DeploymentException e) {
throw new RuntimeException(e);
}
servletContext.setAttribute(ServerContainer.class.getName(), container);
info.containerReady(container);
SecurityActions.addContainer(deploymentInfo.getClassLoader(), container);
deploymentInfo.addListener(Servlets.listener(WebSocketListener.class));
deploymentInfo.addDeploymentCompleteListener(new ServletContextListener() {
@Override
public void contextInitialized(ServletContextEvent sce) {
container.validateDeployment();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
});
}
use of io.undertow.connector.ByteBufferPool in project undertow by undertow-io.
the class ServletOutputStreamImpl method writeTooLargeForBuffer.
private void writeTooLargeForBuffer(byte[] b, int off, int len, ByteBuffer buffer) throws IOException {
// so what we have will not fit.
// We allocate multiple buffers up to MAX_BUFFERS_TO_ALLOCATE
// and put it in them
// if it still dopes not fit we loop, re-using these buffers
StreamSinkChannel channel = this.channel;
if (channel == null) {
this.channel = channel = servletRequestContext.getExchange().getResponseChannel();
}
final ByteBufferPool bufferPool = servletRequestContext.getExchange().getConnection().getByteBufferPool();
ByteBuffer[] buffers = new ByteBuffer[MAX_BUFFERS_TO_ALLOCATE + 1];
PooledByteBuffer[] pooledBuffers = new PooledByteBuffer[MAX_BUFFERS_TO_ALLOCATE];
try {
buffers[0] = buffer;
int bytesWritten = 0;
int rem = buffer.remaining();
buffer.put(b, bytesWritten + off, rem);
buffer.flip();
bytesWritten += rem;
int bufferCount = 1;
for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE; ++i) {
PooledByteBuffer pooled = bufferPool.allocate();
pooledBuffers[bufferCount - 1] = pooled;
buffers[bufferCount++] = pooled.getBuffer();
ByteBuffer cb = pooled.getBuffer();
int toWrite = len - bytesWritten;
if (toWrite > cb.remaining()) {
rem = cb.remaining();
cb.put(b, bytesWritten + off, rem);
cb.flip();
bytesWritten += rem;
} else {
cb.put(b, bytesWritten + off, toWrite);
bytesWritten = len;
cb.flip();
break;
}
}
Channels.writeBlocking(channel, buffers, 0, bufferCount);
while (bytesWritten < len) {
// ok, it did not fit, loop and loop and loop until it is done
bufferCount = 0;
for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE + 1; ++i) {
ByteBuffer cb = buffers[i];
cb.clear();
bufferCount++;
int toWrite = len - bytesWritten;
if (toWrite > cb.remaining()) {
rem = cb.remaining();
cb.put(b, bytesWritten + off, rem);
cb.flip();
bytesWritten += rem;
} else {
cb.put(b, bytesWritten + off, toWrite);
bytesWritten = len;
cb.flip();
break;
}
}
Channels.writeBlocking(channel, buffers, 0, bufferCount);
}
buffer.clear();
} finally {
for (int i = 0; i < pooledBuffers.length; ++i) {
PooledByteBuffer p = pooledBuffers[i];
if (p == null) {
break;
}
p.close();
}
}
}
use of io.undertow.connector.ByteBufferPool in project undertow by undertow-io.
the class UndertowOutputStream method write.
/**
* {@inheritDoc}
*/
public void write(final byte[] b, final int off, final int len) throws IOException {
if (len < 1) {
return;
}
if (exchange.isInIoThread()) {
throw UndertowMessages.MESSAGES.blockingIoFromIOThread();
}
if (anyAreSet(state, FLAG_CLOSED)) {
throw UndertowMessages.MESSAGES.streamIsClosed();
}
// if this is the last of the content
ByteBuffer buffer = buffer();
if (len == contentLength - written || buffer.remaining() < len) {
if (buffer.remaining() < len) {
// so what we have will not fit.
// We allocate multiple buffers up to MAX_BUFFERS_TO_ALLOCATE
// and put it in them
// if it still dopes not fit we loop, re-using these buffers
StreamSinkChannel channel = this.channel;
if (channel == null) {
this.channel = channel = exchange.getResponseChannel();
}
final ByteBufferPool bufferPool = exchange.getConnection().getByteBufferPool();
ByteBuffer[] buffers = new ByteBuffer[MAX_BUFFERS_TO_ALLOCATE + 1];
PooledByteBuffer[] pooledBuffers = new PooledByteBuffer[MAX_BUFFERS_TO_ALLOCATE];
try {
buffers[0] = buffer;
int bytesWritten = 0;
int rem = buffer.remaining();
buffer.put(b, bytesWritten + off, rem);
buffer.flip();
bytesWritten += rem;
int bufferCount = 1;
for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE; ++i) {
PooledByteBuffer pooled = bufferPool.allocate();
pooledBuffers[bufferCount - 1] = pooled;
buffers[bufferCount++] = pooled.getBuffer();
ByteBuffer cb = pooled.getBuffer();
int toWrite = len - bytesWritten;
if (toWrite > cb.remaining()) {
rem = cb.remaining();
cb.put(b, bytesWritten + off, rem);
cb.flip();
bytesWritten += rem;
} else {
cb.put(b, bytesWritten + off, len - bytesWritten);
bytesWritten = len;
cb.flip();
break;
}
}
Channels.writeBlocking(channel, buffers, 0, bufferCount);
while (bytesWritten < len) {
// ok, it did not fit, loop and loop and loop until it is done
bufferCount = 0;
for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE + 1; ++i) {
ByteBuffer cb = buffers[i];
cb.clear();
bufferCount++;
int toWrite = len - bytesWritten;
if (toWrite > cb.remaining()) {
rem = cb.remaining();
cb.put(b, bytesWritten + off, rem);
cb.flip();
bytesWritten += rem;
} else {
cb.put(b, bytesWritten + off, len - bytesWritten);
bytesWritten = len;
cb.flip();
break;
}
}
Channels.writeBlocking(channel, buffers, 0, bufferCount);
}
buffer.clear();
} finally {
for (int i = 0; i < pooledBuffers.length; ++i) {
PooledByteBuffer p = pooledBuffers[i];
if (p == null) {
break;
}
p.close();
}
}
} else {
buffer.put(b, off, len);
if (buffer.remaining() == 0) {
writeBufferBlocking(false);
}
}
} else {
buffer.put(b, off, len);
if (buffer.remaining() == 0) {
writeBufferBlocking(false);
}
}
updateWritten(len);
}
use of io.undertow.connector.ByteBufferPool in project wildfly by wildfly.
the class DistributableSessionTestCase method changeSessionIdResponseCommitted.
public void changeSessionIdResponseCommitted() {
when(this.session.getMetaData()).thenReturn(this.metaData);
when(this.metaData.isNew()).thenReturn(false);
when(this.session.isValid()).thenReturn(true);
io.undertow.server.session.Session session = new DistributableSession(this.manager, this.session, this.config, this.batch, this.closeTask);
// Ugh - all this, just to get HttpServerExchange.isResponseStarted() to return true
Configurable configurable = mock(Configurable.class);
StreamSourceConduit sourceConduit = mock(StreamSourceConduit.class);
ConduitStreamSourceChannel sourceChannel = new ConduitStreamSourceChannel(configurable, sourceConduit);
StreamSinkConduit sinkConduit = mock(StreamSinkConduit.class);
ConduitStreamSinkChannel sinkChannel = new ConduitStreamSinkChannel(configurable, sinkConduit);
StreamConnection stream = mock(StreamConnection.class);
when(stream.getSourceChannel()).thenReturn(sourceChannel);
when(stream.getSinkChannel()).thenReturn(sinkChannel);
ByteBufferPool bufferPool = mock(ByteBufferPool.class);
HttpHandler handler = mock(HttpHandler.class);
HttpServerConnection connection = new HttpServerConnection(stream, bufferPool, handler, OptionMap.create(UndertowOptions.ALWAYS_SET_DATE, false), 0, null);
HttpServerExchange exchange = new HttpServerExchange(connection);
exchange.setProtocol(Protocols.HTTP_1_1);
exchange.getResponseChannel();
SessionConfig config = mock(SessionConfig.class);
Assert.assertThrows(IllegalStateException.class, () -> session.changeSessionId(exchange, config));
}
Aggregations