Skip to content
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

Make EventPipeProviderCallbackData own the filter data #42307

Merged
merged 3 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/src/vm/eventpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1041,9 +1041,9 @@ HANDLE EventPipe::GetWaitHandle(EventPipeSessionID sessionID)
return pSession ? pSession->GetWaitEvent()->GetHandleUNHOSTED() : 0;
}

void EventPipe::InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData)
void EventPipe::InvokeCallback(EventPipeProviderCallbackData *pEventPipeProviderCallbackData)
{
EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
EventPipeProvider::InvokeCallback(pEventPipeProviderCallbackData);
}

EventPipeEventInstance *EventPipe::BuildEventMetadataEvent(EventPipeEventInstance &instance, unsigned int metadataId)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/vm/eventpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class EventPipe
}

while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
InvokeCallback(eventPipeProviderCallbackData);
InvokeCallback(&eventPipeProviderCallbackData);
}

// Returns the a number 0...N representing the processor number this thread is currently
Expand All @@ -158,7 +158,7 @@ class EventPipe
}

private:
static void InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData);
static void InvokeCallback(EventPipeProviderCallbackData *pEventPipeProviderCallbackData);

// Get the event used to write metadata to the event stream.
static EventPipeEventInstance *BuildEventMetadataEvent(EventPipeEventInstance &instance, unsigned int metadataId);
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/src/vm/eventpipecommontypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

void EventPipeProviderCallbackDataQueue::Enqueue(EventPipeProviderCallbackData *pEventPipeProviderCallbackData)
{
SListElem<EventPipeProviderCallbackData> *listnode = new SListElem<EventPipeProviderCallbackData>(); // throws
listnode->m_Value = *pEventPipeProviderCallbackData;
SListElem<EventPipeProviderCallbackData> *listnode = new SListElem<EventPipeProviderCallbackData>(std::move(*pEventPipeProviderCallbackData)); // throws
list.InsertTail(listnode);
}

Expand All @@ -19,7 +18,7 @@ bool EventPipeProviderCallbackDataQueue::TryDequeue(EventPipeProviderCallbackDat
return false;

SListElem<EventPipeProviderCallbackData> *listnode = list.RemoveHead();
*pEventPipeProviderCallbackData = listnode->m_Value;
*pEventPipeProviderCallbackData = std::move(listnode->m_Value);
delete listnode;
return true;
}
Expand Down
125 changes: 117 additions & 8 deletions src/coreclr/src/vm/eventpipecommontypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,129 @@ typedef void (*EventPipeCallback)(
EventFilterDescriptor *FilterData,
void *CallbackContext);

struct EventPipeProviderCallbackData
class EventPipeProviderCallbackData
{
LPCWSTR pFilterData;
EventPipeCallback pCallbackFunction;
bool enabled;
INT64 keywords;
EventPipeEventLevel providerLevel;
void* pCallbackData;
public:
EventPipeProviderCallbackData():
m_pFilterData(nullptr),
m_pCallbackFunction(nullptr),
m_enabled(false),
m_keywords(0),
m_providerLevel(EventPipeEventLevel::LogAlways),
m_pCallbackData(nullptr),
m_pProvider(nullptr)
{

}

EventPipeProviderCallbackData(LPCWSTR pFilterData,
EventPipeCallback pCallbackFunction,
bool enabled,
INT64 keywords,
EventPipeEventLevel providerLevel,
void* pCallbackData,
EventPipeProvider *pProvider) :
m_pFilterData(nullptr),
m_pCallbackFunction(pCallbackFunction),
m_enabled(enabled),
m_keywords(keywords),
m_providerLevel(providerLevel),
m_pCallbackData(pCallbackData),
m_pProvider(pProvider)
{
if (pFilterData != nullptr)
{
// This is the only way to create an EventPipeProviderCallbackData that will copy the
// filter data. The copying is intentional, because sessions die before callbacks happen
// so we cannot cache a pointer to the session's filter data.
size_t bufSize = wcslen(pFilterData) + 1;
m_pFilterData = new WCHAR[bufSize];
wcscpy_s(m_pFilterData, bufSize, pFilterData);
}
}

EventPipeProviderCallbackData(EventPipeProviderCallbackData &&other)
: EventPipeProviderCallbackData()
{
*this = std::move(other);
}

EventPipeProviderCallbackData &operator=(EventPipeProviderCallbackData &&other)
{
std::swap(m_pFilterData, other.m_pFilterData);
m_pCallbackFunction = other.m_pCallbackFunction;
m_enabled = other.m_enabled;
m_keywords = other.m_keywords;
m_providerLevel = other.m_providerLevel;
m_pCallbackData = other.m_pCallbackData;
m_pProvider = other.m_pProvider;

return *this;
}

// We don't want to be unintentionally copying and deleting the filter data any more
// than we have to. Moving (above) is fine, but copying should be avoided.
EventPipeProviderCallbackData(const EventPipeProviderCallbackData &other) = delete;
EventPipeProviderCallbackData &operator=(const EventPipeProviderCallbackData &other) = delete;

~EventPipeProviderCallbackData()
{
if (m_pFilterData != nullptr)
{
delete[] m_pFilterData;
m_pFilterData = nullptr;
}
}

LPCWSTR GetFilterData() const
{
return m_pFilterData;
}

EventPipeCallback GetCallbackFunction() const
{
return m_pCallbackFunction;
}

bool GetEnabled() const
{
return m_enabled;
}

INT64 GetKeywords() const
{
return m_keywords;
}

EventPipeEventLevel GetProviderLevel() const
{
return m_providerLevel;
}

void *GetCallbackData() const
{
return m_pCallbackData;
}

EventPipeProvider *GetProvider() const
{
return m_pProvider;
}

private:
WCHAR *m_pFilterData;
EventPipeCallback m_pCallbackFunction;
bool m_enabled;
INT64 m_keywords;
EventPipeEventLevel m_providerLevel;
void* m_pCallbackData;
EventPipeProvider *m_pProvider;
};

class EventPipeProviderCallbackDataQueue
{
public:
void Enqueue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
void Enqueue(EventPipeProviderCallbackData *pEventPipeProviderCallbackData);
bool TryDequeue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);

private:
Expand Down
28 changes: 14 additions & 14 deletions src/coreclr/src/vm/eventpipeprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void EventPipeProvider::AddEvent(EventPipeEvent &event)
event.RefreshState();
}

/* static */ void EventPipeProvider::InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData)
/* static */ void EventPipeProvider::InvokeCallback(EventPipeProviderCallbackData *pEventPipeProviderCallbackData)
{
CONTRACTL
{
Expand All @@ -205,12 +205,12 @@ void EventPipeProvider::AddEvent(EventPipeEvent &event)
}
Copy link
Member

@jorive jorive Sep 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe add a precondition that the input pointer parameter is not null.

CONTRACTL_END;

LPCWSTR pFilterData = eventPipeProviderCallbackData.pFilterData;
EventPipeCallback pCallbackFunction = eventPipeProviderCallbackData.pCallbackFunction;
bool enabled = eventPipeProviderCallbackData.enabled;
INT64 keywords = eventPipeProviderCallbackData.keywords;
EventPipeEventLevel providerLevel = eventPipeProviderCallbackData.providerLevel;
void *pCallbackData = eventPipeProviderCallbackData.pCallbackData;
LPCWSTR pFilterData = pEventPipeProviderCallbackData->GetFilterData();
EventPipeCallback pCallbackFunction = pEventPipeProviderCallbackData->GetCallbackFunction();
bool enabled = pEventPipeProviderCallbackData->GetEnabled();
INT64 keywords = pEventPipeProviderCallbackData->GetKeywords();
EventPipeEventLevel providerLevel = pEventPipeProviderCallbackData->GetProviderLevel();
void *pCallbackData = pEventPipeProviderCallbackData->GetCallbackData();

bool isEventFilterDescriptorInitialized = false;
EventFilterDescriptor eventFilterDescriptor{};
Expand Down Expand Up @@ -286,13 +286,13 @@ EventPipeProviderCallbackData EventPipeProvider::PrepareCallbackData(
}
CONTRACTL_END;

EventPipeProviderCallbackData result;
result.pFilterData = pFilterData;
result.pCallbackFunction = m_pCallbackFunction;
result.enabled = (m_sessions != 0);
result.providerLevel = providerLevel;
result.keywords = keywords;
result.pCallbackData = m_pCallbackData;
EventPipeProviderCallbackData result(pFilterData,
m_pCallbackFunction,
(m_sessions != 0),
keywords,
providerLevel,
m_pCallbackData,
this);
return result;
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/eventpipeprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class EventPipeProvider
LPCWSTR pFilterData);

// Invoke the provider callback.
static void InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData);
static void InvokeCallback(EventPipeProviderCallbackData *pEventPipeProviderCallbackData);

// Specifies whether or not the provider was deleted, but that deletion
// was deferred until after tracing is stopped.
Expand Down