Skip to content

Commit

Permalink
Remove IDNMDOwner indirections in the regular importing scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky committed Jun 19, 2024
1 parent 25a0229 commit 77ac92a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 14 deletions.
6 changes: 3 additions & 3 deletions src/interfaces/dispenser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ namespace
threadSafeUnknown.Attach(new ControllingIUnknown());

// Define an IDNMDOwner* tear-off here so the thread-safe object can be identified as a DNMD object.
(void)threadSafeUnknown->CreateAndAddTearOff<DelegatingDNMDOwner>(owner);
(void)threadSafeUnknown->CreateAndAddTearOff<ThreadSafeImportEmit<MetadataImportRO, MetadataEmit>>(import, emit);
// DelegatingDNMDOwner took ownership of owner, so we can return our thread-safe object here.
(void)threadSafeUnknown->CreateAndAddTearOff<DelegatingDNMDOwner>(handle_view);
(void)threadSafeUnknown->CreateAndAddTearOff<ThreadSafeImportEmit<MetadataImportRO, MetadataEmit>>(std::move(unknown), import, emit);
// ThreadSafeImportEmit took ownership of owner through unknown.
return threadSafeUnknown;
}

Expand Down
16 changes: 10 additions & 6 deletions src/interfaces/dnmdowner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ struct IDNMDOwner : IUnknown
virtual mdhandle_t MetaData() = 0;
};

class DNMDOwner;

// We use a reference wrapper around the handle to allow the handle to be swapped out.
// We plan to use swapping to implement table sorting as DNMD itself does not support
// sorting tables or remapping tokens.
Expand All @@ -27,9 +29,9 @@ struct IDNMDOwner : IUnknown
class mdhandle_view final
{
private:
IDNMDOwner* _owner;
DNMDOwner* _owner;
public:
explicit mdhandle_view(IDNMDOwner* owner)
explicit mdhandle_view(DNMDOwner* owner)
: _owner{ owner }
{
}
Expand All @@ -42,10 +44,7 @@ class mdhandle_view final

mdhandle_view& operator=(mdhandle_view&& other) = default;

mdhandle_t get() const
{
return _owner->MetaData();
}
mdhandle_t get() const;

bool operator==(std::nullptr_t) const
{
Expand Down Expand Up @@ -110,4 +109,9 @@ class DNMDOwner final : public TearOffBase<IDNMDOwner>
}
};

inline mdhandle_t mdhandle_view::get() const
{
return _owner->MetaData();
}

#endif // !_SRC_INTERFACES_DNMDOWNER_HPP_
15 changes: 10 additions & 5 deletions src/interfaces/threadsafe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
#include <cstdint>
#include <mutex>

// An tear-off that provides ownership semantics of an inner IDNMDOwner object.
// A tear-off that re-exposes an mdhandle_view as an IDNMDOwner*.
class DelegatingDNMDOwner final : public TearOffBase<IDNMDOwner>
{
dncp::com_ptr<IDNMDOwner> _inner;
mdhandle_view _inner;

protected:
virtual bool TryGetInterfaceOnThis(REFIID riid, void** ppvObject) override
Expand All @@ -31,7 +31,7 @@ class DelegatingDNMDOwner final : public TearOffBase<IDNMDOwner>
}

public:
DelegatingDNMDOwner(IUnknown* controllingUnknown, IDNMDOwner* inner)
DelegatingDNMDOwner(IUnknown* controllingUnknown, mdhandle_view inner)
: TearOffBase(controllingUnknown)
, _inner{ inner }
{ }
Expand All @@ -40,14 +40,16 @@ class DelegatingDNMDOwner final : public TearOffBase<IDNMDOwner>

mdhandle_t MetaData() override
{
return _inner->MetaData();
return _inner.get();
}
};

template<typename TImport, typename TEmit>
class ThreadSafeImportEmit : public TearOffBase<IMetaDataImport2, IMetaDataEmit2, IMetaDataAssemblyImport, IMetaDataAssemblyEmit>
{
pal::ReadWriteLock _lock;
// owning reference to the thread-unsafe object that provides the underlying implementation.
dncp::com_ptr<ControllingIUnknown> _threadUnsafe;
// non-owning reference to the concrete non-locking implementations
TImport* _import;
TEmit* _emit;
Expand Down Expand Up @@ -80,12 +82,15 @@ class ThreadSafeImportEmit : public TearOffBase<IMetaDataImport2, IMetaDataEmit2
}

public:
ThreadSafeImportEmit(IUnknown* controllingUnknown, TImport* import, TEmit* emit)
ThreadSafeImportEmit(IUnknown* controllingUnknown, dncp::com_ptr<ControllingIUnknown>&& threadUnsafe, TImport* import, TEmit* emit)
: TearOffBase(controllingUnknown)
, _lock { }
, _threadUnsafe{ std::move(threadUnsafe) }
, _import{ import }
, _emit{ emit }
{
assert(_import != nullptr);
assert(_emit != nullptr);
}

virtual ~ThreadSafeImportEmit() = default;
Expand Down

0 comments on commit 77ac92a

Please sign in to comment.