-
Notifications
You must be signed in to change notification settings - Fork 5.1k
[EventPipe] End user_events session upon continuation_stream closure #117435
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
base: main
Are you sure you want to change the base?
[EventPipe] End user_events session upon continuation_stream closure #117435
Conversation
cc: @pavelsavara for websocket poll implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for detecting remote disconnections on user_events-based EventPipe sessions by extending IPC streams with polling capabilities and wiring up a continuation stream to session logic.
- Introduce
IpcStreamPollFunc
in IPC vtables and implementds_ipc_stream_poll
variants - Define
IpcContinuationStream
and addep_ipc_continuation_stream_connection_closed
for hangup detection - Refactor session streaming thread to handle
EP_SESSION_TYPE_USEREVENTS
and unifiedep_session_type_uses_streaming_thread
predicate
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
src/native/eventpipe/ep-types-forward.h | Forward-declare IpcContinuationStream |
src/native/eventpipe/ep-stream.h | Define IpcContinuationStream struct and closure API |
src/native/eventpipe/ep-stream.c | Add ep_ipc_stream_poll_vcall and continuation-stream check |
src/native/eventpipe/ep-session.h | Add continuation_stream field and streaming-thread predicate |
src/native/eventpipe/ep-session.c | Refactor streaming thread to support user events and cleanup |
src/native/eventpipe/ep-ipc-stream.h | Add IpcStreamPollFunc and ep_ipc_stream_poll_vcall prototype |
src/native/eventpipe/ep-ipc-pal-types.h | Define EventPipeIpcPollEvents enum and poll timeout constant |
src/native/eventpipe/ds-ipc.c | Replace DS_IPC_POLL_EVENTS_* with EP_IPC_POLL_EVENTS_* |
src/native/eventpipe/ds-ipc-pal.h | Declare ds_ipc_stream_poll |
src/native/eventpipe/ds-ipc-pal-websocket.c | Implement WebSocket poll func and update vtable |
src/native/eventpipe/ds-ipc-pal-types.h | Remove old DiagnosticsIpcPollEvents enum |
src/native/eventpipe/ds-ipc-pal-socket.c | Add socket poll func and vtable entry |
src/native/eventpipe/ds-ipc-pal-namedpipe.c | Stub out named pipe poll func |
src/native/eventpipe/ds-eventpipe-protocol.c | Always pass ds_ipc_stream_get_stream_ref(stream) |
a529a85
to
c7fc5e6
Compare
src/native/eventpipe/ep-stream.h
Outdated
@@ -355,5 +355,26 @@ ep_ipc_stream_writer_write ( | |||
uint32_t bytes_to_write, | |||
uint32_t *bytes_written); | |||
|
|||
/* | |||
* IpcContinuationStream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defining a new struct to wrap IpcStream seems unnecessary. Couldn't we just make the continuation_stream field in the session be type IpcStream*?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, we can. I just wasn't sure if IpcStream was meant to only be a base class that should be derived for different implementations, like how the different PAL implementations of DiagnosticsIpcStream all just derive from IpcStream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think IpcStream is meant to be a base class for different types of stream implementations, for example socket stream vs named pipe stream vs websocket stream. Its a bit less obvious because even though derived types have different implementations they are all reusing the same 'DiagnosticsIpcStream' type name. At some point in the future we could rename them SocketIpcStream, NamedPipeIpcStream, etc to make the inheritance pattern clearer. Sidestepping the naming, unless we are implementing a new transport I wouldn't expect a new stream derived type is needed.
Revert moving IpcPollEvents to ep-ipc-pal-types header Use IpcStream base type directly in sessions Omit websocket ipc_stream_poll_func implementation Change continuation stream poll timeout to infinite Change returned PollEvent to none upon timeout
c131816
to
37c0056
Compare
ep-stream.h for ep_ipc_stream_writer_alloc that was transitively included by ep-file.h ep-ipc-stream.h for ep_ipc_stream_poll_vcall
@@ -71,6 +71,9 @@ struct _EventPipeSession_Internal { | |||
volatile uint32_t ref_count; | |||
// The user_events_data file descriptor to register Tracepoints and write user_events to. | |||
int user_events_data_fd; | |||
// The IPC continuation stream from initializing the session through the diagnostic server | |||
// Currently only initialized for user_events sessions. | |||
IpcStream *stream; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to do it in this PR, but going forward I believe we should do different versions of this struct depending on the type and move specific fields into sub types instead of having a fields in one struct where type dictates what fields is applicable without any further information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I think we can have a Refactoring PR where we split up the versions of the struct, also migrate the IPC types to its own file, and move the user_events_data fd into the Stream structure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So IPC namespace, Clarify the IpcStream inheritance naming, this, and the followup work from the main user_events PR (#115265 (comment) ,#115265 (comment), #115265 (comment))
DS_IPC_POLL_EVENTS_HANGUP = 0x02, // connection remotely closed | ||
DS_IPC_POLL_EVENTS_ERR = 0x04, // error | ||
DS_IPC_POLL_EVENTS_UNKNOWN = 0x80 // unknown state | ||
} DiagnosticsIpcPollEvents; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it already have been discussed, but maybe we should just drop EP/DS from this so its "common" meaning IPC_POLL_EVENTS_*, IpcPollEvents, IPC_TIMEOUT_INFINITE and going forward we might put all the low level IPC stuff into its own IPC namespace and share that code cross components.
Remove prefix from IpcPollEvents enums and infinite timeout define Expand connection closed detection to error case
User_events-based EventPipe sessions should end when the profiling process disconnects from the Diagnostic Port.
This PR does the following:
ds_ipc_stream_poll
based onds_ipc_poll
ep_ipc_continuation_stream_connection_closed
to detect disconnects.Testing
Manual E2E testing with the same C program as #115265, except putting a
getchar
before closing the socket from the client side.