Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
3e6535d8
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
3e6535d8
编写于
1月 14, 2021
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
shared process - implement message port connections and wire in
上级
cd906568
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
372 addition
and
131 deletion
+372
-131
src/vs/base/parts/ipc/browser/ipc.mp.ts
src/vs/base/parts/ipc/browser/ipc.mp.ts
+22
-0
src/vs/base/parts/ipc/common/ipc.electron.ts
src/vs/base/parts/ipc/common/ipc.electron.ts
+1
-1
src/vs/base/parts/ipc/common/ipc.mp.ts
src/vs/base/parts/ipc/common/ipc.mp.ts
+89
-0
src/vs/base/parts/ipc/electron-main/ipc.mp.ts
src/vs/base/parts/ipc/electron-main/ipc.mp.ts
+52
-0
src/vs/base/parts/ipc/electron-sandbox/ipc.electron.ts
src/vs/base/parts/ipc/electron-sandbox/ipc.electron.ts
+1
-1
src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts
src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts
+45
-0
src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
.../code/electron-browser/sharedProcess/sharedProcessMain.ts
+11
-64
src/vs/code/electron-main/app.ts
src/vs/code/electron-main/app.ts
+15
-11
src/vs/code/electron-main/sharedProcess.ts
src/vs/code/electron-main/sharedProcess.ts
+56
-27
src/vs/code/electron-main/window.ts
src/vs/code/electron-main/window.ts
+1
-1
src/vs/code/electron-sandbox/issue/issueReporterMain.ts
src/vs/code/electron-sandbox/issue/issueReporterMain.ts
+2
-2
src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts
...e/electron-sandbox/processExplorer/processExplorerMain.ts
+2
-2
src/vs/platform/ipc/electron-sandbox/mainProcessService.ts
src/vs/platform/ipc/electron-sandbox/mainProcessService.ts
+27
-2
src/vs/workbench/electron-browser/desktop.main.ts
src/vs/workbench/electron-browser/desktop.main.ts
+2
-2
src/vs/workbench/electron-sandbox/desktop.main.ts
src/vs/workbench/electron-sandbox/desktop.main.ts
+2
-2
src/vs/workbench/services/sharedProcess/electron-browser/sharedProcessService.ts
...es/sharedProcess/electron-browser/sharedProcessService.ts
+44
-16
未找到文件。
src/vs/base/parts/ipc/browser/ipc.mp.ts
0 → 100644
浏览文件 @
3e6535d8
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Client
as
MessagePortClient
}
from
'
vs/base/parts/ipc/common/ipc.mp
'
;
/**
* An implementation of a `IPCClient` on top of DOM `MessagePort`.
*/
export
class
Client
extends
MessagePortClient
implements
IDisposable
{
/**
* @param clientId a way to uniquely identify this client among
* other clients. this is important for routing because every
* client can also be a server
*/
constructor
(
port
:
MessagePort
,
clientId
:
string
)
{
super
(
port
,
clientId
);
}
}
src/vs/base/parts/ipc/common/ipc.electron.ts
浏览文件 @
3e6535d8
...
@@ -28,7 +28,7 @@ export class Protocol implements IMessagePassingProtocol {
...
@@ -28,7 +28,7 @@ export class Protocol implements IMessagePassingProtocol {
}
}
}
}
dis
pose
():
void
{
dis
connect
():
void
{
this
.
sender
.
send
(
'
vscode:disconnect
'
,
null
);
this
.
sender
.
send
(
'
vscode:disconnect
'
,
null
);
}
}
}
}
src/vs/base/parts/ipc/common/ipc.mp.ts
0 → 100644
浏览文件 @
3e6535d8
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
IMessagePassingProtocol
,
IPCClient
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
VSBuffer
}
from
'
vs/base/common/buffer
'
;
/**
* Declare minimal `MessageEvent` and `MessagePort` interfaces here
* so that this utility can be used both from `browser` and
* `electron-main` namespace where message ports are available.
*/
export
interface
MessageEvent
{
/**
* For our use we only consider `Uint8Array` and `disconnect`
* a valid data transfer via message ports. Our protocol
* implementation is buffer based and we only need the explicit
* `disconnect` because message ports currently have no way of
* indicating when their connection is closed.
*/
data
:
Uint8Array
|
'
disconnect
'
;
}
export
interface
MessagePort
{
addEventListener
(
type
:
'
message
'
,
listener
:
(
this
:
MessagePort
,
e
:
MessageEvent
)
=>
unknown
):
void
;
removeEventListener
(
type
:
'
message
'
,
listener
:
(
this
:
MessagePort
,
e
:
MessageEvent
)
=>
unknown
):
void
;
postMessage
(
message
:
Uint8Array
|
'
disconnect
'
):
void
;
start
():
void
;
close
():
void
;
}
/**
* The MessagePort `Protocol` leverages MessagePort style IPC communication
* for the implementation of the `IMessagePassingProtocol`. That style of API
* is a simple `onmessage` / `postMessage` pattern.
*/
export
class
Protocol
implements
IMessagePassingProtocol
{
private
readonly
onRawData
=
Event
.
fromDOMEventEmitter
<
VSBuffer
|
'
disconnect
'
>
(
this
.
port
,
'
message
'
,
(
e
:
MessageEvent
)
=>
e
.
data
===
'
disconnect
'
?
e
.
data
:
VSBuffer
.
wrap
(
e
.
data
));
readonly
onMessage
=
Event
.
filter
(
this
.
onRawData
,
data
=>
data
!==
'
disconnect
'
)
as
Event
<
VSBuffer
>
;
readonly
onDisconnect
=
Event
.
signal
(
Event
.
filter
(
this
.
onRawData
,
data
=>
data
===
'
disconnect
'
));
constructor
(
private
port
:
MessagePort
)
{
// we must call start() to ensure messages are flowing
port
.
start
();
// when the other end disconnects, ensure that we close
// our end as well to stay in sync
Event
.
once
(
this
.
onDisconnect
)(()
=>
port
.
close
());
}
send
(
message
:
VSBuffer
):
void
{
this
.
port
.
postMessage
(
message
.
buffer
);
}
disconnect
():
void
{
this
.
port
.
postMessage
(
'
disconnect
'
);
this
.
port
.
close
();
}
}
/**
* An implementation of a `IPCClient` on top of MessagePort style IPC communication.
*/
export
class
Client
extends
IPCClient
implements
IDisposable
{
private
protocol
:
Protocol
;
constructor
(
port
:
MessagePort
,
clientId
:
string
)
{
const
protocol
=
new
Protocol
(
port
);
super
(
protocol
,
clientId
);
this
.
protocol
=
protocol
;
}
dispose
():
void
{
this
.
protocol
.
disconnect
();
}
}
src/vs/base/parts/ipc/electron-main/ipc.mp.ts
0 → 100644
浏览文件 @
3e6535d8
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
BrowserWindow
,
ipcMain
,
IpcMainEvent
,
MessagePortMain
}
from
'
electron
'
;
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
generateUuid
}
from
'
vs/base/common/uuid
'
;
import
{
Client
as
MessagePortClient
}
from
'
vs/base/parts/ipc/common/ipc.mp
'
;
/**
* An implementation of a `IPCClient` on top of Electron `MessagePortMain`.
*/
export
class
Client
extends
MessagePortClient
implements
IDisposable
{
/**
* @param clientId a way to uniquely identify this client among
* other clients. this is important for routing because every
* client can also be a server
*/
constructor
(
port
:
MessagePortMain
,
clientId
:
string
)
{
super
({
addEventListener
:
(
type
,
listener
)
=>
port
.
addListener
(
type
,
listener
),
removeEventListener
:
(
type
,
listener
)
=>
port
.
removeListener
(
type
,
listener
),
postMessage
:
message
=>
port
.
postMessage
(
message
),
start
:
()
=>
port
.
start
(),
close
:
()
=>
port
.
close
()
},
clientId
);
}
}
/**
* This method opens a message channel connection
* in the target window. The target window needs
* to use the `Server` from `electron-sandbox/ipc.mp`.
*/
export
async
function
connect
(
window
:
BrowserWindow
):
Promise
<
MessagePortMain
>
{
// Ask to create message channel inside the window
// and send over a UUID to correlate the response
const
nonce
=
generateUuid
();
window
.
webContents
.
send
(
'
vscode:createMessageChannel
'
,
nonce
);
// Wait until the window has returned the `MessagePort`
// We need to filter by the `nonce` to ensure we listen
// to the right response.
const
onMessageChannelResult
=
Event
.
fromNodeEventEmitter
<
{
nonce
:
string
,
port
:
MessagePortMain
}
>
(
ipcMain
,
'
vscode:createMessageChannelResult
'
,
(
e
:
IpcMainEvent
,
nonce
:
string
)
=>
({
nonce
,
port
:
e
.
ports
[
0
]
}));
const
{
port
}
=
await
Event
.
toPromise
(
Event
.
once
(
Event
.
filter
(
onMessageChannelResult
,
e
=>
e
.
nonce
===
nonce
)));
return
port
;
}
src/vs/base/parts/ipc/electron-sandbox/ipc.electron.ts
浏览文件 @
3e6535d8
...
@@ -33,6 +33,6 @@ export class Client extends IPCClient implements IDisposable {
...
@@ -33,6 +33,6 @@ export class Client extends IPCClient implements IDisposable {
}
}
dispose
():
void
{
dispose
():
void
{
this
.
protocol
.
dis
pose
();
this
.
protocol
.
dis
connect
();
}
}
}
}
src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts
0 → 100644
浏览文件 @
3e6535d8
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
ipcRenderer
}
from
'
vs/base/parts/sandbox/electron-sandbox/globals
'
;
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
ClientConnectionEvent
,
IPCServer
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
Protocol
as
MessagePortProtocol
}
from
'
vs/base/parts/ipc/common/ipc.mp
'
;
/**
* An implementation of a `IPCServer` on top of MessagePort style IPC communication.
* The clients register themselves via Electron IPC transfer.
*/
export
class
Server
extends
IPCServer
{
private
static
getOnDidClientConnect
():
Event
<
ClientConnectionEvent
>
{
// Clients connect via `vscode:createMessageChannel` to get a
// `MessagePort` that is ready to be used. For every connection
// we create a pair of message ports and send it back.
//
// The `nonce` is included so that the main side has a chance to
// correlate the response back to the sender.
const
onCreateMessageChannel
=
Event
.
fromNodeEventEmitter
<
string
>
(
ipcRenderer
,
'
vscode:createMessageChannel
'
,
(
_
,
nonce
:
string
)
=>
nonce
);
return
Event
.
map
(
onCreateMessageChannel
,
nonce
=>
{
// Create a new pair of ports and protocol for this connection
const
{
port1
:
incomingPort
,
port2
:
outgoingPort
}
=
new
MessageChannel
();
const
protocol
=
new
MessagePortProtocol
(
incomingPort
);
const
result
:
ClientConnectionEvent
=
{
protocol
,
onDidClientDisconnect
:
protocol
.
onDisconnect
};
// Send one port back to the requestor
ipcRenderer
.
postMessage
(
'
vscode:createMessageChannelResult
'
,
nonce
,
[
outgoingPort
]);
return
result
;
});
}
constructor
()
{
super
(
Server
.
getOnDidClientConnect
());
}
}
src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
浏览文件 @
3e6535d8
...
@@ -6,9 +6,8 @@
...
@@ -6,9 +6,8 @@
import
product
from
'
vs/platform/product/common/product
'
;
import
product
from
'
vs/platform/product/common/product
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
fs
from
'
fs
'
;
import
{
gracefulify
}
from
'
graceful-fs
'
;
import
{
gracefulify
}
from
'
graceful-fs
'
;
import
{
isWindows
}
from
'
vs/base/common/platform
'
;
import
{
Server
as
MessagePortServer
}
from
'
vs/base/parts/ipc/electron-sandbox/ipc.mp
'
;
import
{
IChannel
,
IServerChannel
,
StaticRouter
,
createChannelSender
,
createChannelReceiver
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
StaticRouter
,
createChannelSender
,
createChannelReceiver
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
serve
as
nodeIPCServe
,
Server
as
NodeIPCServer
,
connect
as
nodeIPCConnect
}
from
'
vs/base/parts/ipc/node/ipc.net
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
SyncDescriptor
}
from
'
vs/platform/instantiation/common/descriptors
'
;
import
{
SyncDescriptor
}
from
'
vs/platform/instantiation/common/descriptors
'
;
import
{
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiationService
'
;
import
{
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiationService
'
;
...
@@ -40,7 +39,7 @@ import { NodeCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/co
...
@@ -40,7 +39,7 @@ import { NodeCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/co
import
{
LanguagePackCachedDataCleaner
}
from
'
vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner
'
;
import
{
LanguagePackCachedDataCleaner
}
from
'
vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner
'
;
import
{
StorageDataCleaner
}
from
'
vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner
'
;
import
{
StorageDataCleaner
}
from
'
vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner
'
;
import
{
LogsDataCleaner
}
from
'
vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner
'
;
import
{
LogsDataCleaner
}
from
'
vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner
'
;
import
{
IMainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IMainProcessService
,
MessagePortMainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
SpdLogService
}
from
'
vs/platform/log/node/spdlogService
'
;
import
{
SpdLogService
}
from
'
vs/platform/log/node/spdlogService
'
;
import
{
DiagnosticsService
,
IDiagnosticsService
}
from
'
vs/platform/diagnostics/node/diagnosticsService
'
;
import
{
DiagnosticsService
,
IDiagnosticsService
}
from
'
vs/platform/diagnostics/node/diagnosticsService
'
;
import
{
FileService
}
from
'
vs/platform/files/common/fileService
'
;
import
{
FileService
}
from
'
vs/platform/files/common/fileService
'
;
...
@@ -79,34 +78,16 @@ import { DeprecatedExtensionsCleaner } from 'vs/code/electron-browser/sharedProc
...
@@ -79,34 +78,16 @@ import { DeprecatedExtensionsCleaner } from 'vs/code/electron-browser/sharedProc
import
{
onUnexpectedError
,
setUnexpectedErrorHandler
}
from
'
vs/base/common/errors
'
;
import
{
onUnexpectedError
,
setUnexpectedErrorHandler
}
from
'
vs/base/common/errors
'
;
import
{
toErrorMessage
}
from
'
vs/base/common/errorMessage
'
;
import
{
toErrorMessage
}
from
'
vs/base/common/errorMessage
'
;
class
MainProcessService
implements
IMainProcessService
{
declare
readonly
_serviceBrand
:
undefined
;
constructor
(
private
server
:
NodeIPCServer
,
private
mainRouter
:
StaticRouter
)
{
}
getChannel
(
channelName
:
string
):
IChannel
{
return
this
.
server
.
getChannel
(
channelName
,
this
.
mainRouter
);
}
registerChannel
(
channelName
:
string
,
channel
:
IServerChannel
<
string
>
):
void
{
this
.
server
.
registerChannel
(
channelName
,
channel
);
}
}
class
SharedProcessMain
extends
Disposable
{
class
SharedProcessMain
extends
Disposable
{
constructor
(
private
server
:
NodeIPCServer
,
private
configuration
:
ISharedProcessConfiguration
)
{
private
server
=
this
.
_register
(
new
MessagePortServer
());
constructor
(
private
configuration
:
ISharedProcessConfiguration
)
{
super
();
super
();
// Enable gracefulFs
// Enable gracefulFs
gracefulify
(
fs
);
gracefulify
(
fs
);
this
.
_register
(
this
.
server
);
this
.
registerListeners
();
this
.
registerListeners
();
}
}
...
@@ -160,7 +141,7 @@ class SharedProcessMain extends Disposable {
...
@@ -160,7 +141,7 @@ class SharedProcessMain extends Disposable {
// Log
// Log
const
mainRouter
=
new
StaticRouter
(
ctx
=>
ctx
===
'
main
'
);
const
mainRouter
=
new
StaticRouter
(
ctx
=>
ctx
===
'
main
'
);
const
loggerClient
=
new
LoggerChannelClient
(
this
.
server
.
getChannel
(
'
logger
'
,
mainRouter
));
const
loggerClient
=
new
LoggerChannelClient
(
this
.
server
.
getChannel
(
'
logger
'
,
mainRouter
));
// we only use this for log levels
const
multiplexLogger
=
this
.
_register
(
new
MultiplexLogService
([
const
multiplexLogger
=
this
.
_register
(
new
MultiplexLogService
([
this
.
_register
(
new
ConsoleLogService
(
this
.
configuration
.
logLevel
)),
this
.
_register
(
new
ConsoleLogService
(
this
.
configuration
.
logLevel
)),
this
.
_register
(
new
SpdLogService
(
'
sharedprocess
'
,
environmentService
.
logsPath
,
this
.
configuration
.
logLevel
))
this
.
_register
(
new
SpdLogService
(
'
sharedprocess
'
,
environmentService
.
logsPath
,
this
.
configuration
.
logLevel
))
...
@@ -170,7 +151,7 @@ class SharedProcessMain extends Disposable {
...
@@ -170,7 +151,7 @@ class SharedProcessMain extends Disposable {
services
.
set
(
ILogService
,
logService
);
services
.
set
(
ILogService
,
logService
);
// Main Process
// Main Process
const
mainProcessService
=
new
MainProcessService
(
this
.
server
,
mainRouter
);
const
mainProcessService
=
new
M
essagePortM
ainProcessService
(
this
.
server
,
mainRouter
);
services
.
set
(
IMainProcessService
,
mainProcessService
);
services
.
set
(
IMainProcessService
,
mainProcessService
);
// Files
// Files
...
@@ -345,48 +326,14 @@ class SharedProcessMain extends Disposable {
...
@@ -345,48 +326,14 @@ class SharedProcessMain extends Disposable {
}
}
}
}
function
setupNodeIPC
(
hook
:
string
):
Promise
<
NodeIPCServer
>
{
function
setup
(
retry
:
boolean
):
Promise
<
NodeIPCServer
>
{
return
nodeIPCServe
(
hook
).
then
(
null
,
err
=>
{
if
(
!
retry
||
isWindows
||
err
.
code
!==
'
EADDRINUSE
'
)
{
return
Promise
.
reject
(
err
);
}
// should retry, not windows and eaddrinuse
return
nodeIPCConnect
(
hook
,
''
).
then
(
client
=>
{
// we could connect to a running instance. this is not good, abort
client
.
dispose
();
return
Promise
.
reject
(
new
Error
(
'
There is an instance already running.
'
));
},
err
=>
{
// it happens on Linux and OS X that the pipe is left behind
// let's delete it, since we can't connect to it
// and the retry the whole thing
try
{
fs
.
unlinkSync
(
hook
);
}
catch
(
e
)
{
return
Promise
.
reject
(
new
Error
(
'
Error deleting the shared ipc hook.
'
));
}
return
setup
(
false
);
}
);
});
}
return
setup
(
true
);
}
export
async
function
main
(
configuration
:
ISharedProcessConfiguration
):
Promise
<
void
>
{
export
async
function
main
(
configuration
:
ISharedProcessConfiguration
):
Promise
<
void
>
{
// await IPC connection and signal this back to electron-main
// create shared process and signal back to main that we are
const
server
=
await
setupNodeIPC
(
configuration
.
sharedIPCHandle
);
// ready to accept message ports as client connections
const
sharedProcess
=
new
SharedProcessMain
(
configuration
);
ipcRenderer
.
send
(
'
vscode:shared-process->electron-main=ipc-ready
'
);
ipcRenderer
.
send
(
'
vscode:shared-process->electron-main=ipc-ready
'
);
// await initialization and signal this back to electron-main
// await initialization and signal this back to electron-main
const
sharedProcess
=
new
SharedProcessMain
(
server
,
configuration
);
await
sharedProcess
.
open
();
await
sharedProcess
.
open
();
ipcRenderer
.
send
(
'
vscode:shared-process->electron-main=init-done
'
);
ipcRenderer
.
send
(
'
vscode:shared-process->electron-main=init-done
'
);
}
}
src/vs/code/electron-main/app.ts
浏览文件 @
3e6535d8
...
@@ -13,8 +13,8 @@ import { IUpdateService } from 'vs/platform/update/common/update';
...
@@ -13,8 +13,8 @@ import { IUpdateService } from 'vs/platform/update/common/update';
import
{
UpdateChannel
}
from
'
vs/platform/update/electron-main/updateIpc
'
;
import
{
UpdateChannel
}
from
'
vs/platform/update/electron-main/updateIpc
'
;
import
{
getDelayedChannel
,
StaticRouter
,
createChannelReceiver
,
createChannelSender
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
getDelayedChannel
,
StaticRouter
,
createChannelReceiver
,
createChannelSender
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
Server
as
ElectronIPCServer
}
from
'
vs/base/parts/ipc/electron-main/ipc.electron
'
;
import
{
Server
as
ElectronIPCServer
}
from
'
vs/base/parts/ipc/electron-main/ipc.electron
'
;
import
{
Client
as
NodeIPCClient
}
from
'
vs/base/parts/ipc/common
/ipc.net
'
;
import
{
Server
as
NodeIPCServer
}
from
'
vs/base/parts/ipc/node
/ipc.net
'
;
import
{
Server
as
NodeIPCServer
,
connect
as
nodeIPCConnect
}
from
'
vs/base/parts/ipc/node/ipc.net
'
;
import
{
Client
as
MessagePortClient
}
from
'
vs/base/parts/ipc/electron-main/ipc.mp
'
;
import
{
SharedProcess
}
from
'
vs/code/electron-main/sharedProcess
'
;
import
{
SharedProcess
}
from
'
vs/code/electron-main/sharedProcess
'
;
import
{
LaunchMainService
,
ILaunchMainService
}
from
'
vs/platform/launch/electron-main/launchMainService
'
;
import
{
LaunchMainService
,
ILaunchMainService
}
from
'
vs/platform/launch/electron-main/launchMainService
'
;
import
{
IInstantiationService
,
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IInstantiationService
,
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
...
@@ -426,16 +426,20 @@ export class CodeApplication extends Disposable {
...
@@ -426,16 +426,20 @@ export class CodeApplication extends Disposable {
// Spawn shared process after the first window has opened and 3s have passed
// Spawn shared process after the first window has opened and 3s have passed
const
sharedProcess
=
this
.
instantiationService
.
createInstance
(
SharedProcess
,
machineId
,
this
.
userEnv
);
const
sharedProcess
=
this
.
instantiationService
.
createInstance
(
SharedProcess
,
machineId
,
this
.
userEnv
);
const
sharedProcessClient
=
sharedProcess
.
whenIpcReady
().
then
(
()
=>
{
const
sharedProcessClient
=
(
async
()
=>
{
this
.
logService
.
trace
(
'
Shared process: IPC ready
'
);
this
.
logService
.
trace
(
'
Main->SharedProcess#connect
'
);
return
nodeIPCConnect
(
this
.
environmentService
.
sharedIPCHandle
,
'
main
'
);
const
port
=
await
sharedProcess
.
connect
();
});
const
sharedProcessReady
=
sharedProcess
.
whenReady
().
then
(()
=>
{
this
.
logService
.
trace
(
'
Main->SharedProcess#connect: connection established
'
);
this
.
logService
.
trace
(
'
Shared process: init ready
'
);
return
new
MessagePortClient
(
port
,
'
main
'
);
})();
const
sharedProcessReady
=
(
async
()
=>
{
await
sharedProcess
.
whenReady
();
return
sharedProcessClient
;
return
sharedProcessClient
;
});
})
()
;
this
.
lifecycleMainService
.
when
(
LifecycleMainPhase
.
AfterWindowOpen
).
then
(()
=>
{
this
.
lifecycleMainService
.
when
(
LifecycleMainPhase
.
AfterWindowOpen
).
then
(()
=>
{
this
.
_register
(
new
RunOnceScheduler
(
async
()
=>
{
this
.
_register
(
new
RunOnceScheduler
(
async
()
=>
{
sharedProcess
.
spawn
(
await
resolveShellEnv
(
this
.
logService
,
this
.
environmentService
.
args
,
process
.
env
));
sharedProcess
.
spawn
(
await
resolveShellEnv
(
this
.
logService
,
this
.
environmentService
.
args
,
process
.
env
));
...
@@ -482,7 +486,7 @@ export class CodeApplication extends Disposable {
...
@@ -482,7 +486,7 @@ export class CodeApplication extends Disposable {
return
machineId
;
return
machineId
;
}
}
private
async
createServices
(
machineId
:
string
,
sharedProcess
:
SharedProcess
,
sharedProcessReady
:
Promise
<
NodeIPCClient
<
string
>
>
):
Promise
<
IInstantiationService
>
{
private
async
createServices
(
machineId
:
string
,
sharedProcess
:
SharedProcess
,
sharedProcessReady
:
Promise
<
MessagePortClient
>
):
Promise
<
IInstantiationService
>
{
const
services
=
new
ServiceCollection
();
const
services
=
new
ServiceCollection
();
switch
(
process
.
platform
)
{
switch
(
process
.
platform
)
{
...
@@ -584,7 +588,7 @@ export class CodeApplication extends Disposable {
...
@@ -584,7 +588,7 @@ export class CodeApplication extends Disposable {
});
});
}
}
private
openFirstWindow
(
accessor
:
ServicesAccessor
,
electronIpcServer
:
ElectronIPCServer
,
sharedProcessClient
:
Promise
<
NodeIPCClient
<
string
>
>
,
fileProtocolHandler
:
FileProtocolHandler
):
ICodeWindow
[]
{
private
openFirstWindow
(
accessor
:
ServicesAccessor
,
electronIpcServer
:
ElectronIPCServer
,
sharedProcessClient
:
Promise
<
MessagePortClient
>
,
fileProtocolHandler
:
FileProtocolHandler
):
ICodeWindow
[]
{
// Register more Main IPC services
// Register more Main IPC services
const
launchMainService
=
accessor
.
get
(
ILaunchMainService
);
const
launchMainService
=
accessor
.
get
(
ILaunchMainService
);
...
...
src/vs/code/electron-main/sharedProcess.ts
浏览文件 @
3e6535d8
...
@@ -3,9 +3,8 @@
...
@@ -3,9 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
*--------------------------------------------------------------------------------------------*/
import
{
memoize
}
from
'
vs/base/common/decorators
'
;
import
{
BrowserWindow
,
ipcMain
,
Event
,
MessagePortMain
}
from
'
electron
'
;
import
{
IEnvironmentMainService
}
from
'
vs/platform/environment/electron-main/environmentMainService
'
;
import
{
IEnvironmentMainService
}
from
'
vs/platform/environment/electron-main/environmentMainService
'
;
import
{
BrowserWindow
,
ipcMain
,
Event
}
from
'
electron
'
;
import
{
ISharedProcess
}
from
'
vs/platform/sharedProcess/electron-main/sharedProcessMainService
'
;
import
{
ISharedProcess
}
from
'
vs/platform/sharedProcess/electron-main/sharedProcessMainService
'
;
import
{
Barrier
}
from
'
vs/base/common/async
'
;
import
{
Barrier
}
from
'
vs/base/common/async
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
...
@@ -15,14 +14,13 @@ import { FileAccess } from 'vs/base/common/network';
...
@@ -15,14 +14,13 @@ import { FileAccess } from 'vs/base/common/network';
import
{
browserCodeLoadingCacheStrategy
}
from
'
vs/base/common/platform
'
;
import
{
browserCodeLoadingCacheStrategy
}
from
'
vs/base/common/platform
'
;
import
{
ISharedProcessConfiguration
}
from
'
vs/platform/sharedProcess/node/sharedProcess
'
;
import
{
ISharedProcessConfiguration
}
from
'
vs/platform/sharedProcess/node/sharedProcess
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
connect
as
connectMessagePort
}
from
'
vs/base/parts/ipc/electron-main/ipc.mp
'
;
import
{
assertIsDefined
}
from
'
vs/base/common/types
'
;
export
class
SharedProcess
extends
Disposable
implements
ISharedProcess
{
export
class
SharedProcess
extends
Disposable
implements
ISharedProcess
{
private
readonly
whenSpawnedBarrier
=
new
Barrier
();
private
readonly
whenSpawnedBarrier
=
new
Barrier
();
// overall ready promise when shared process signals initialization is done
private
readonly
_whenReady
=
new
Promise
<
void
>
(
resolve
=>
ipcMain
.
once
(
'
vscode:shared-process->electron-main=init-done
'
,
()
=>
resolve
()));
private
window
:
BrowserWindow
|
undefined
=
undefined
;
private
window
:
BrowserWindow
|
undefined
=
undefined
;
private
windowCloseListener
:
((
event
:
Event
)
=>
void
)
|
undefined
=
undefined
;
private
windowCloseListener
:
((
event
:
Event
)
=>
void
)
|
undefined
=
undefined
;
...
@@ -40,7 +38,16 @@ export class SharedProcess extends Disposable implements ISharedProcess {
...
@@ -40,7 +38,16 @@ export class SharedProcess extends Disposable implements ISharedProcess {
}
}
private
registerListeners
():
void
{
private
registerListeners
():
void
{
// Lifecycle
this
.
_register
(
this
.
lifecycleMainService
.
onWillShutdown
(()
=>
this
.
onWillShutdown
()));
this
.
_register
(
this
.
lifecycleMainService
.
onWillShutdown
(()
=>
this
.
onWillShutdown
()));
// Shared process connections
ipcMain
.
on
(
'
vscode:createSharedProcessMessageChannel
'
,
async
(
e
,
nonce
:
string
)
=>
{
const
port
=
await
this
.
connect
();
e
.
sender
.
postMessage
(
'
vscode:createSharedProcessMessageChannelResult
'
,
nonce
,
[
port
]);
});
}
}
private
onWillShutdown
():
void
{
private
onWillShutdown
():
void
{
...
@@ -50,7 +57,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
...
@@ -50,7 +57,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
}
}
// Signal exit to shared process when shutting down
// Signal exit to shared process when shutting down
window
.
webContents
.
send
(
'
vscode:electron-main->shared-process=exit
'
);
// TODO verify call
window
.
webContents
.
send
(
'
vscode:electron-main->shared-process=exit
'
);
// Shut the shared process down when we are quitting
// Shut the shared process down when we are quitting
//
//
...
@@ -75,17 +82,45 @@ export class SharedProcess extends Disposable implements ISharedProcess {
...
@@ -75,17 +82,45 @@ export class SharedProcess extends Disposable implements ISharedProcess {
},
0
);
},
0
);
}
}
@
memoize
private
_whenReady
:
Promise
<
void
>
|
undefined
=
undefined
;
private
get
_whenIpcReady
():
Promise
<
void
>
{
whenReady
():
Promise
<
void
>
{
if
(
!
this
.
_whenReady
)
{
// Overall signal that the shared process window was loaded and
// all services within have been created.
this
.
_whenReady
=
new
Promise
<
void
>
(
resolve
=>
ipcMain
.
once
(
'
vscode:shared-process->electron-main=init-done
'
,
()
=>
{
this
.
logService
.
trace
(
'
SharedProcess: Overall ready
'
);
resolve
();
}));
}
return
this
.
_whenReady
;
}
private
_whenIpcReady
:
Promise
<
void
>
|
undefined
=
undefined
;
private
get
whenIpcReady
()
{
if
(
!
this
.
_whenIpcReady
)
{
this
.
_whenIpcReady
=
(
async
()
=>
{
// Always wait for `spawn()`
await
this
.
whenSpawnedBarrier
.
wait
();
// Create window for shared process
this
.
createWindow
();
// Create window for shared proces
s
// Listener
s
this
.
createWindow
();
this
.
registerWindowListeners
();
// Listeners
// Wait for window indicating that IPC connections are accepted
this
.
registerWindowListeners
();
await
new
Promise
<
void
>
(
resolve
=>
ipcMain
.
once
(
'
vscode:shared-process->electron-main=ipc-ready
'
,
()
=>
{
this
.
logService
.
trace
(
'
SharedProcess: IPC ready
'
);
resolve
();
}));
})();
}
// complete IPC-ready promise when shared process signals this to us
return
this
.
_whenIpcReady
;
return
new
Promise
<
void
>
(
resolve
=>
ipcMain
.
once
(
'
vscode:shared-process->electron-main=ipc-ready
'
,
()
=>
resolve
(
undefined
)));
}
}
private
createWindow
():
void
{
private
createWindow
():
void
{
...
@@ -151,7 +186,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
...
@@ -151,7 +186,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
// Crashes & Unrsponsive & Failed to load
// Crashes & Unrsponsive & Failed to load
this
.
window
.
webContents
.
on
(
'
render-process-gone
'
,
(
event
,
details
)
=>
this
.
logService
.
error
(
`[VS Code]: sharedProcess crashed (detail:
${
details
?.
reason
}
)`
));
this
.
window
.
webContents
.
on
(
'
render-process-gone
'
,
(
event
,
details
)
=>
this
.
logService
.
error
(
`[VS Code]: sharedProcess crashed (detail:
${
details
?.
reason
}
)`
));
this
.
window
.
on
(
'
unresponsive
'
,
()
=>
this
.
logService
.
error
(
'
[VS Code]: detected unresponsive sharedProcess window
'
));
this
.
window
.
on
(
'
unresponsive
'
,
()
=>
this
.
logService
.
error
(
'
[VS Code]: detected unresponsive sharedProcess window
'
));
this
.
window
.
webContents
.
on
(
'
did-fail-load
'
,
(
event
:
Event
,
errorCode
:
number
,
errorDescription
:
string
)
=>
this
.
logService
.
warn
(
'
[VS Code]: fail to load sharedProcess window,
'
,
errorDescription
));
this
.
window
.
webContents
.
on
(
'
did-fail-load
'
,
(
event
,
errorCode
,
errorDescription
)
=>
this
.
logService
.
warn
(
'
[VS Code]: fail to load sharedProcess window,
'
,
errorDescription
));
}
}
spawn
(
userEnv
:
NodeJS
.
ProcessEnv
):
void
{
spawn
(
userEnv
:
NodeJS
.
ProcessEnv
):
void
{
...
@@ -161,20 +196,14 @@ export class SharedProcess extends Disposable implements ISharedProcess {
...
@@ -161,20 +196,14 @@ export class SharedProcess extends Disposable implements ISharedProcess {
this
.
whenSpawnedBarrier
.
open
();
this
.
whenSpawnedBarrier
.
open
();
}
}
async
whenReady
():
Promise
<
void
>
{
async
connect
():
Promise
<
MessagePortMain
>
{
// Always wait for `spawn()`
await
this
.
whenSpawnedBarrier
.
wait
();
await
this
.
_whenReady
;
}
async
whenIpcReady
():
Promise
<
void
>
{
//
Always wait for `spawn()`
//
Wait for shared process being ready to accept connection
await
this
.
when
SpawnedBarrier
.
wait
()
;
await
this
.
when
IpcReady
;
await
this
.
_whenIpcReady
;
// Connect and return message port
const
window
=
assertIsDefined
(
this
.
window
);
return
connectMessagePort
(
window
);
}
}
toggle
():
void
{
toggle
():
void
{
...
...
src/vs/code/electron-main/window.ts
浏览文件 @
3e6535d8
...
@@ -415,7 +415,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
...
@@ -415,7 +415,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// Crashes & Unrsponsive & Failed to load
// Crashes & Unrsponsive & Failed to load
this
.
_win
.
webContents
.
on
(
'
render-process-gone
'
,
(
event
,
details
)
=>
this
.
onWindowError
(
WindowError
.
CRASHED
,
details
));
this
.
_win
.
webContents
.
on
(
'
render-process-gone
'
,
(
event
,
details
)
=>
this
.
onWindowError
(
WindowError
.
CRASHED
,
details
));
this
.
_win
.
on
(
'
unresponsive
'
,
()
=>
this
.
onWindowError
(
WindowError
.
UNRESPONSIVE
));
this
.
_win
.
on
(
'
unresponsive
'
,
()
=>
this
.
onWindowError
(
WindowError
.
UNRESPONSIVE
));
this
.
_win
.
webContents
.
on
(
'
did-fail-load
'
,
(
event
:
Event
,
errorCode
:
number
,
errorDescription
:
string
)
=>
this
.
logService
.
warn
(
'
[VS Code]: fail to load workbench window,
'
,
errorDescription
));
this
.
_win
.
webContents
.
on
(
'
did-fail-load
'
,
(
event
,
errorCode
,
errorDescription
)
=>
this
.
logService
.
warn
(
'
[VS Code]: fail to load workbench window,
'
,
errorDescription
));
// Window close
// Window close
this
.
_win
.
on
(
'
closed
'
,
()
=>
{
this
.
_win
.
on
(
'
closed
'
,
()
=>
{
...
...
src/vs/code/electron-sandbox/issue/issueReporterMain.ts
浏览文件 @
3e6535d8
...
@@ -22,7 +22,7 @@ import BaseHtml from 'vs/code/electron-sandbox/issue/issueReporterPage';
...
@@ -22,7 +22,7 @@ import BaseHtml from 'vs/code/electron-sandbox/issue/issueReporterPage';
import
{
localize
}
from
'
vs/nls
'
;
import
{
localize
}
from
'
vs/nls
'
;
import
{
isRemoteDiagnosticError
,
SystemInfo
}
from
'
vs/platform/diagnostics/common/diagnostics
'
;
import
{
isRemoteDiagnosticError
,
SystemInfo
}
from
'
vs/platform/diagnostics/common/diagnostics
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
IMainProcessService
,
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IMainProcessService
,
ElectronIPC
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IssueReporterData
,
IssueReporterExtensionData
,
IssueReporterFeatures
,
IssueReporterStyles
,
IssueType
}
from
'
vs/platform/issue/common/issue
'
;
import
{
IssueReporterData
,
IssueReporterExtensionData
,
IssueReporterFeatures
,
IssueReporterStyles
,
IssueType
}
from
'
vs/platform/issue/common/issue
'
;
import
{
IWindowConfiguration
}
from
'
vs/platform/windows/common/windows
'
;
import
{
IWindowConfiguration
}
from
'
vs/platform/windows/common/windows
'
;
import
{
Codicon
}
from
'
vs/base/common/codicons
'
;
import
{
Codicon
}
from
'
vs/base/common/codicons
'
;
...
@@ -266,7 +266,7 @@ export class IssueReporter extends Disposable {
...
@@ -266,7 +266,7 @@ export class IssueReporter extends Disposable {
private
initServices
(
configuration
:
IssueReporterConfiguration
):
void
{
private
initServices
(
configuration
:
IssueReporterConfiguration
):
void
{
const
serviceCollection
=
new
ServiceCollection
();
const
serviceCollection
=
new
ServiceCollection
();
const
mainProcessService
=
new
MainProcessService
(
configuration
.
windowId
);
const
mainProcessService
=
new
ElectronIPC
MainProcessService
(
configuration
.
windowId
);
serviceCollection
.
set
(
IMainProcessService
,
mainProcessService
);
serviceCollection
.
set
(
IMainProcessService
,
mainProcessService
);
this
.
nativeHostService
=
new
NativeHostService
(
configuration
.
windowId
,
mainProcessService
)
as
INativeHostService
;
this
.
nativeHostService
=
new
NativeHostService
(
configuration
.
windowId
,
mainProcessService
)
as
INativeHostService
;
...
...
src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts
浏览文件 @
3e6535d8
...
@@ -17,7 +17,7 @@ import { ProcessItem } from 'vs/base/common/processes';
...
@@ -17,7 +17,7 @@ import { ProcessItem } from 'vs/base/common/processes';
import
*
as
dom
from
'
vs/base/browser/dom
'
;
import
*
as
dom
from
'
vs/base/browser/dom
'
;
import
{
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
isRemoteDiagnosticError
,
IRemoteDiagnosticError
}
from
'
vs/platform/diagnostics/common/diagnostics
'
;
import
{
isRemoteDiagnosticError
,
IRemoteDiagnosticError
}
from
'
vs/platform/diagnostics/common/diagnostics
'
;
import
{
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
ElectronIPC
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
ByteSize
}
from
'
vs/platform/files/common/files
'
;
import
{
ByteSize
}
from
'
vs/platform/files/common/files
'
;
import
{
IListVirtualDelegate
}
from
'
vs/base/browser/ui/list/list
'
;
import
{
IListVirtualDelegate
}
from
'
vs/base/browser/ui/list/list
'
;
import
{
IDataSource
,
ITreeNode
,
ITreeRenderer
}
from
'
vs/base/browser/ui/tree/tree
'
;
import
{
IDataSource
,
ITreeNode
,
ITreeRenderer
}
from
'
vs/base/browser/ui/tree/tree
'
;
...
@@ -233,7 +233,7 @@ class ProcessExplorer {
...
@@ -233,7 +233,7 @@ class ProcessExplorer {
private
tree
:
DataTree
<
any
,
ProcessTree
|
MachineProcessInformation
|
ProcessItem
|
ProcessInformation
|
IRemoteDiagnosticError
,
any
>
|
undefined
;
private
tree
:
DataTree
<
any
,
ProcessTree
|
MachineProcessInformation
|
ProcessItem
|
ProcessInformation
|
IRemoteDiagnosticError
,
any
>
|
undefined
;
constructor
(
windowId
:
number
,
private
data
:
ProcessExplorerData
)
{
constructor
(
windowId
:
number
,
private
data
:
ProcessExplorerData
)
{
const
mainProcessService
=
new
MainProcessService
(
windowId
);
const
mainProcessService
=
new
ElectronIPC
MainProcessService
(
windowId
);
this
.
nativeHostService
=
new
NativeHostService
(
windowId
,
mainProcessService
)
as
INativeHostService
;
this
.
nativeHostService
=
new
NativeHostService
(
windowId
,
mainProcessService
)
as
INativeHostService
;
this
.
applyStyles
(
data
.
styles
);
this
.
applyStyles
(
data
.
styles
);
...
...
src/vs/platform/ipc/electron-sandbox/mainProcessService.ts
浏览文件 @
3e6535d8
...
@@ -3,10 +3,11 @@
...
@@ -3,10 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
*--------------------------------------------------------------------------------------------*/
import
{
IChannel
,
IServerChannel
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IChannel
,
IServerChannel
,
StaticRouter
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
Client
as
IPCElectronClient
}
from
'
vs/base/parts/ipc/electron-sandbox/ipc.electron
'
;
import
{
Client
as
IPCElectronClient
}
from
'
vs/base/parts/ipc/electron-sandbox/ipc.electron
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
Server
}
from
'
vs/base/parts/ipc/electron-sandbox/ipc.mp
'
;
export
const
IMainProcessService
=
createDecorator
<
IMainProcessService
>
(
'
mainProcessService
'
);
export
const
IMainProcessService
=
createDecorator
<
IMainProcessService
>
(
'
mainProcessService
'
);
...
@@ -19,7 +20,10 @@ export interface IMainProcessService {
...
@@ -19,7 +20,10 @@ export interface IMainProcessService {
registerChannel
(
channelName
:
string
,
channel
:
IServerChannel
<
string
>
):
void
;
registerChannel
(
channelName
:
string
,
channel
:
IServerChannel
<
string
>
):
void
;
}
}
export
class
MainProcessService
extends
Disposable
implements
IMainProcessService
{
/**
* An implementation of `IMainProcessService` that leverages Electron's IPC.
*/
export
class
ElectronIPCMainProcessService
extends
Disposable
implements
IMainProcessService
{
declare
readonly
_serviceBrand
:
undefined
;
declare
readonly
_serviceBrand
:
undefined
;
...
@@ -41,3 +45,24 @@ export class MainProcessService extends Disposable implements IMainProcessServic
...
@@ -41,3 +45,24 @@ export class MainProcessService extends Disposable implements IMainProcessServic
this
.
mainProcessConnection
.
registerChannel
(
channelName
,
channel
);
this
.
mainProcessConnection
.
registerChannel
(
channelName
,
channel
);
}
}
}
}
/**
* An implementation of `IMainProcessService` that leverages MessagePorts.
*/
export
class
MessagePortMainProcessService
implements
IMainProcessService
{
declare
readonly
_serviceBrand
:
undefined
;
constructor
(
private
server
:
Server
,
private
router
:
StaticRouter
)
{
}
getChannel
(
channelName
:
string
):
IChannel
{
return
this
.
server
.
getChannel
(
channelName
,
this
.
router
);
}
registerChannel
(
channelName
:
string
,
channel
:
IServerChannel
<
string
>
):
void
{
this
.
server
.
registerChannel
(
channelName
,
channel
);
}
}
src/vs/workbench/electron-browser/desktop.main.ts
浏览文件 @
3e6535d8
...
@@ -32,7 +32,7 @@ import { IWorkbenchConfigurationService } from 'vs/workbench/services/configurat
...
@@ -32,7 +32,7 @@ import { IWorkbenchConfigurationService } from 'vs/workbench/services/configurat
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
registerWindowDriver
}
from
'
vs/platform/driver/electron-browser/driver
'
;
import
{
registerWindowDriver
}
from
'
vs/platform/driver/electron-browser/driver
'
;
import
{
IMainProcessService
,
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IMainProcessService
,
ElectronIPC
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
RemoteAuthorityResolverService
}
from
'
vs/platform/remote/electron-sandbox/remoteAuthorityResolverService
'
;
import
{
RemoteAuthorityResolverService
}
from
'
vs/platform/remote/electron-sandbox/remoteAuthorityResolverService
'
;
import
{
IRemoteAuthorityResolverService
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
{
IRemoteAuthorityResolverService
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
{
RemoteAgentService
}
from
'
vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl
'
;
import
{
RemoteAgentService
}
from
'
vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl
'
;
...
@@ -181,7 +181,7 @@ class DesktopMain extends Disposable {
...
@@ -181,7 +181,7 @@ class DesktopMain extends Disposable {
// Main Process
// Main Process
const
mainProcessService
=
this
.
_register
(
new
MainProcessService
(
this
.
configuration
.
windowId
));
const
mainProcessService
=
this
.
_register
(
new
ElectronIPC
MainProcessService
(
this
.
configuration
.
windowId
));
serviceCollection
.
set
(
IMainProcessService
,
mainProcessService
);
serviceCollection
.
set
(
IMainProcessService
,
mainProcessService
);
// Environment
// Environment
...
...
src/vs/workbench/electron-sandbox/desktop.main.ts
浏览文件 @
3e6535d8
...
@@ -19,7 +19,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
...
@@ -19,7 +19,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import
{
IWorkbenchConfigurationService
}
from
'
vs/workbench/services/configuration/common/configuration
'
;
import
{
IWorkbenchConfigurationService
}
from
'
vs/workbench/services/configuration/common/configuration
'
;
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IMainProcessService
,
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IMainProcessService
,
ElectronIPC
MainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IRemoteAuthorityResolverService
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
{
IRemoteAuthorityResolverService
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
{
IRemoteAgentService
}
from
'
vs/workbench/services/remote/common/remoteAgentService
'
;
import
{
IRemoteAgentService
}
from
'
vs/workbench/services/remote/common/remoteAgentService
'
;
import
{
FileService
}
from
'
vs/platform/files/common/fileService
'
;
import
{
FileService
}
from
'
vs/platform/files/common/fileService
'
;
...
@@ -153,7 +153,7 @@ class DesktopMain extends Disposable {
...
@@ -153,7 +153,7 @@ class DesktopMain extends Disposable {
// Main Process
// Main Process
const
mainProcessService
=
this
.
_register
(
new
MainProcessService
(
this
.
configuration
.
windowId
));
const
mainProcessService
=
this
.
_register
(
new
ElectronIPC
MainProcessService
(
this
.
configuration
.
windowId
));
serviceCollection
.
set
(
IMainProcessService
,
mainProcessService
);
serviceCollection
.
set
(
IMainProcessService
,
mainProcessService
);
// Environment
// Environment
...
...
src/vs/workbench/services/sharedProcess/electron-browser/sharedProcessService.ts
浏览文件 @
3e6535d8
...
@@ -3,38 +3,66 @@
...
@@ -3,38 +3,66 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
*--------------------------------------------------------------------------------------------*/
import
{
Client
as
NodeIPCClient
}
from
'
vs/base/parts/ipc/common/ipc.net
'
;
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
connect
as
nodeIPCConnect
}
from
'
vs/base/parts/ipc/node/ipc.net
'
;
import
{
IpcRendererEvent
}
from
'
vs/base/parts/sandbox/electron-sandbox/electronTypes
'
;
import
{
ipcRenderer
}
from
'
vs/base/parts/sandbox/electron-sandbox/globals
'
;
import
{
Client
as
MessagePortClient
}
from
'
vs/base/parts/ipc/common/ipc.mp
'
;
import
{
IChannel
,
IServerChannel
,
getDelayedChannel
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IChannel
,
IServerChannel
,
getDelayedChannel
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IMainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
IMainProcessService
}
from
'
vs/platform/ipc/electron-sandbox/mainProcessService
'
;
import
{
ISharedProcessService
}
from
'
vs/platform/sharedProcess/electron-browser/sharedProcessService
'
;
import
{
ISharedProcessService
}
from
'
vs/platform/sharedProcess/electron-browser/sharedProcessService
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
INativeWorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/electron-sandbox/environmentService
'
;
import
{
INativeHostService
}
from
'
vs/platform/native/electron-sandbox/native
'
;
import
{
INativeHostService
}
from
'
vs/platform/native/electron-sandbox/native
'
;
import
{
generateUuid
}
from
'
vs/base/common/uuid
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
ILifecycleService
}
from
'
vs/workbench/services/lifecycle/common/lifecycle
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
export
class
SharedProcessService
implements
ISharedProcessService
{
export
class
SharedProcessService
extends
Disposable
implements
ISharedProcessService
{
declare
readonly
_serviceBrand
:
undefined
;
declare
readonly
_serviceBrand
:
undefined
;
private
withSharedProcessConnection
:
Promise
<
NodeIPCClient
<
string
>>
;
private
readonly
sharedProcessMainChannel
=
this
.
mainProcessService
.
getChannel
(
'
sharedProcess
'
)
;
private
sharedProcessMainChannel
:
IChannel
;
private
readonly
withSharedProcessConnection
:
Promise
<
MessagePortClient
>
;
constructor
(
constructor
(
@
IMainProcessService
mainProcessService
:
IMainProcessService
,
@
IMainProcessService
private
readonly
mainProcessService
:
IMainProcessService
,
@
INativeHostService
nativeHostService
:
INativeHostService
,
@
INativeHostService
private
readonly
nativeHostService
:
INativeHostService
,
@
INativeWorkbenchEnvironmentService
environmentService
:
INativeWorkbenchEnvironmentService
@
ILogService
private
readonly
logService
:
ILogService
,
@
ILifecycleService
private
readonly
lifecycleService
:
ILifecycleService
)
{
)
{
this
.
sharedProcessMainChannel
=
mainProcessService
.
getChannel
(
'
sharedProcess
'
);
super
(
);
this
.
withSharedProcessConnection
=
(
async
()
=>
{
this
.
withSharedProcessConnection
=
this
.
connect
();
await
this
.
whenReady
();
return
nodeIPCConnect
(
environmentService
.
sharedIPCHandle
,
`window:
${
nativeHostService
.
windowId
}
`
);
this
.
registerListeners
();
})();
}
}
private
whenReady
():
Promise
<
void
>
{
private
registerListeners
():
void
{
return
this
.
sharedProcessMainChannel
.
call
(
'
whenReady
'
);
// Lifecycle
this
.
lifecycleService
.
onWillShutdown
(()
=>
this
.
dispose
());
}
private
async
connect
():
Promise
<
MessagePortClient
>
{
this
.
logService
.
trace
(
'
Workbench->SharedProcess#connect
'
);
// await the shared process to be ready
await
this
.
sharedProcessMainChannel
.
call
(
'
whenReady
'
);
// Ask to create message channel inside the window
// and send over a UUID to correlate the response
const
nonce
=
generateUuid
();
ipcRenderer
.
send
(
'
vscode:createSharedProcessMessageChannel
'
,
nonce
);
// Wait until the main side has returned the `MessagePort`
// We need to filter by the `nonce` to ensure we listen
// to the right response.
const
onMessageChannelResult
=
Event
.
fromNodeEventEmitter
<
{
nonce
:
string
,
port
:
MessagePort
}
>
(
ipcRenderer
,
'
vscode:createSharedProcessMessageChannelResult
'
,
(
e
:
IpcRendererEvent
,
nonce
:
string
)
=>
({
nonce
,
port
:
e
.
ports
[
0
]
}));
const
{
port
}
=
await
Event
.
toPromise
(
Event
.
once
(
Event
.
filter
(
onMessageChannelResult
,
e
=>
e
.
nonce
===
nonce
)));
this
.
logService
.
trace
(
'
Workbench->SharedProcess#connect: connection established
'
);
return
this
.
_register
(
new
MessagePortClient
(
port
,
`window:
${
this
.
nativeHostService
.
windowId
}
`
));
}
}
getChannel
(
channelName
:
string
):
IChannel
{
getChannel
(
channelName
:
string
):
IChannel
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录