-
Notifications
You must be signed in to change notification settings - Fork 26
Support launch by using named pipe #162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2ceb4de
fix - Only send build target count during initialization (#153)
jdneo 8aa9a1f
Merge branch 'microsoft:develop' into merge-with-named-pipe
Jiaaming 1906d98
change launcher param passing method
ab96f22
Merge branch 'merge-with-named-pipe' of https://github.com/Jiaaming/b…
c668ac4
refine NamedPipeStream.java constructor
885e90f
refine NamedPipeStream class structure
c2a77e0
Merge branch 'microsoft:develop' into merge-with-named-pipe
Jiaaming 2af044a
Fix: comments
c68a3de
Fix: comments
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
220 changes: 220 additions & 0 deletions
220
server/src/main/java/com/microsoft/java/bs/core/internal/utils/ServerNamedPipeStream.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,220 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. | ||
|
|
||
| package com.microsoft.java.bs.core.internal.utils; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| import java.io.OutputStream; | ||
| import java.net.StandardProtocolFamily; | ||
| import java.net.UnixDomainSocketAddress; | ||
| import java.nio.ByteBuffer; | ||
| import java.nio.channels.AsynchronousFileChannel; | ||
| import java.nio.channels.ReadableByteChannel; | ||
| import java.nio.channels.SocketChannel; | ||
| import java.nio.channels.WritableByteChannel; | ||
| import java.nio.file.StandardOpenOption; | ||
| import java.util.concurrent.ExecutionException; | ||
| import java.util.concurrent.Future; | ||
|
|
||
| /** | ||
| * A factory for creating the streams for supported transmission methods. | ||
| * | ||
| * @author Gorkem Ercan | ||
| * | ||
| */ | ||
|
|
||
| public class ServerNamedPipeStream { | ||
|
Jiaaming marked this conversation as resolved.
Outdated
|
||
| private String pipeName; | ||
| private StreamProvider provider; | ||
|
|
||
| public ServerNamedPipeStream(String pipeName) { | ||
| this.pipeName = pipeName; | ||
| } | ||
|
|
||
| interface StreamProvider { | ||
| InputStream getInputStream() throws IOException; | ||
|
|
||
| OutputStream getOutputStream() throws IOException; | ||
| } | ||
|
|
||
| /** | ||
| * PipeStreamProvider. | ||
| */ | ||
| protected final class PipeStreamProvider implements StreamProvider { | ||
|
|
||
| private InputStream input; | ||
| private OutputStream output; | ||
| private String pipeName = ServerNamedPipeStream.this.pipeName; | ||
|
|
||
| public PipeStreamProvider() { | ||
| initializeNamedPipe(); | ||
| } | ||
|
|
||
| @Override | ||
| public InputStream getInputStream() throws IOException { | ||
| return input; | ||
| } | ||
|
|
||
| @Override | ||
| public OutputStream getOutputStream() throws IOException { | ||
| return output; | ||
| } | ||
|
|
||
| private void initializeNamedPipe() { | ||
| File pipeFile = new File(this.pipeName); | ||
| if (isWindows()) { | ||
| try { | ||
| AsynchronousFileChannel clientChannel = AsynchronousFileChannel.open( | ||
| pipeFile.toPath(), | ||
| StandardOpenOption.READ, | ||
| StandardOpenOption.WRITE); | ||
| input = new NamedPipeInputStream(clientChannel); | ||
| output = new NamedPipeOutputStream(clientChannel); | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| try { | ||
| UnixDomainSocketAddress socketAddress = UnixDomainSocketAddress.of(pipeFile.toPath()); | ||
| SocketChannel channel = SocketChannel.open(StandardProtocolFamily.UNIX); | ||
| channel.connect(socketAddress); | ||
| input = new NamedPipeInputStream(channel); | ||
| output = new NamedPipeOutputStream(channel); | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * NamedPipeInputStream. | ||
| */ | ||
| public class NamedPipeInputStream extends InputStream { | ||
|
|
||
| private ReadableByteChannel unixChannel; | ||
| private AsynchronousFileChannel winChannel; | ||
| private ByteBuffer buffer = ByteBuffer.allocate(1024); | ||
| private int readyBytes = 0; | ||
|
|
||
| public NamedPipeInputStream(ReadableByteChannel channel) { | ||
| this.unixChannel = channel; | ||
| } | ||
|
|
||
| public NamedPipeInputStream(AsynchronousFileChannel channel) { | ||
| this.winChannel = channel; | ||
| } | ||
|
|
||
| @Override | ||
| public int read() throws IOException { | ||
| if (buffer.position() < readyBytes) { | ||
| return buffer.get() & 0xFF; | ||
| } | ||
| try { | ||
| buffer.clear(); | ||
| if (winChannel != null) { | ||
| readyBytes = winChannel.read(buffer, 0).get(); | ||
| } else { | ||
| readyBytes = unixChannel.read(buffer); | ||
| } | ||
| if (readyBytes == -1) { | ||
| return -1; // EOF | ||
| } | ||
| buffer.flip(); | ||
| return buffer.get() & 0xFF; | ||
| } catch (InterruptedException | ExecutionException e) { | ||
| throw new IOException(e); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * NamedPipeOutputStream. | ||
| */ | ||
| public class NamedPipeOutputStream extends OutputStream { | ||
| private WritableByteChannel unixChannel; | ||
| private AsynchronousFileChannel winChannel; | ||
| private ByteBuffer buffer = ByteBuffer.allocate(1); | ||
|
|
||
| public NamedPipeOutputStream(WritableByteChannel channel) { | ||
| this.unixChannel = channel; | ||
| } | ||
|
|
||
| public NamedPipeOutputStream(AsynchronousFileChannel channel) { | ||
| this.winChannel = channel; | ||
| } | ||
|
|
||
| @Override | ||
| public void write(int b) throws IOException { | ||
| buffer.clear(); | ||
| buffer.put((byte) b); | ||
| buffer.position(0); | ||
| if (winChannel != null) { | ||
| Future<Integer> result = winChannel.write(buffer, 0); | ||
| try { | ||
| result.get(); | ||
| } catch (Exception e) { | ||
| throw new IOException(e); | ||
| } | ||
| } else { | ||
| unixChannel.write(buffer); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void write(byte[] b) throws IOException { | ||
| final int buffer_size = 1024; | ||
| int blocks = b.length / buffer_size; | ||
| int writeBytes = 0; | ||
| for (int i = 0; i <= blocks; i++) { | ||
| int offset = i * buffer_size; | ||
| int length = Math.min(b.length - writeBytes, buffer_size); | ||
| if (length <= 0) { | ||
| break; | ||
| } | ||
| writeBytes += length; | ||
| ByteBuffer buffer = ByteBuffer.wrap(b, offset, length); | ||
| if (winChannel != null) { | ||
| Future<Integer> result = winChannel.write(buffer, 0); | ||
| try { | ||
| result.get(); | ||
| } catch (Exception e) { | ||
| throw new IOException(e); | ||
| } | ||
| } else { | ||
| unixChannel.write(buffer); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * getSelectedStream. | ||
| */ | ||
| public StreamProvider getSelectedStream() { | ||
| if (provider == null) { | ||
| provider = createProvider(); | ||
| } | ||
| return provider; | ||
| } | ||
|
|
||
| private StreamProvider createProvider() { | ||
|
|
||
| return new PipeStreamProvider(); | ||
| } | ||
|
|
||
| public InputStream getInputStream() throws IOException { | ||
| return getSelectedStream().getInputStream(); | ||
| } | ||
|
|
||
| public OutputStream getOutputStream() throws IOException { | ||
| return getSelectedStream().getOutputStream(); | ||
| } | ||
|
|
||
| private static boolean isWindows() { | ||
| return System.getProperty("os.name").toLowerCase().contains("win"); | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.