SBListener not using a shared_ptr internally?

Hey,

I am currently working on lldb bindings for javascript (v8) but it
seems that the API is giving me some troubles.

What I am doing is to basically wrap SB* objects into V8 objects, and
since SB objects contain a shared_ptr into an internal class I think I
can simply copy construct them.

To return a wrapped SB object by some Javascript function, I am simply
copy constructing the SB object into the wrapper object which is
dynamically allocated and when the Javascript object is garbage
collected it will also destroy the SBObject (And also the shared_ptr,
So it should be save I guess?).

Okay, so far so good but I detected some inconsistency when trying to
wrap SBListener. The deal was to make SBListener::WaitForEvent
non-blocking, to do that I am creating a new thread which calls
WaitForEvents, when it returns and the event is valid, the callbacks
given from the Javascript code is called.

There is a catch when doing this. I have to track the threads which
belong to a specific SBListener. But there is not actually easy way to
do this because SB objects are just simply shared_ptr. I noticed the
GetSP function which returns the shared_ptr of an SBListener, this
would be a way to solve this issue as I could use a map which maps the
internal SBListener pointer to a Class object which manages the thread
and stuff (SBListenerWorker).

// etc. mutex, ...
static std::unordered_map<void*, SBListenerWorker*> ListenerWorkers;

GetSP is protected so I had to create a new derived class:

class SBListener_Internal : public lldb::SBListener {
public:
  SBListener_Internal() = default;
  SBListener_Internal(const lldb::SBListener& listener)
      : lldb::SBListener{listener} {
  }
  ~SBListener_Internal() = default;

  void* GetInternalPtr() {
    return reinterpret_cast<void*>(GetSP().get());
  }
};

I had some worried about if the SBListener object could be destroyed
at some point and the internal pointer would still be in the
"ListenerWorkers" map so
to avoid that I copied the the SBListener object into the class which
manages the thread and stuff (SBListenerWorker), that means that the
reference counter should be still > 0 when all other shared_ptrs are
destroyed.

Now to the actual problem, it turns out that GetInternalPtr() actually
returns nullptr and instead uses m_opaque_ptr for calling internal
functions.
This means that the SBListener object isn't actually using a
shared_ptr internally, which brings another question up if it is save
to use the SBListener across thread? What happens if the SBListener
gets destroyed.

What version of the lldb sources are you working with? I changed the SBListener over to using only the ListenerSP internally
in r262863.

Jim

One question is why are you trying to make SBListener::WaitForEvent non-blocking? Seems like an implementation that changes the behavior of the API is going to make the port less useful. Can you go into some detail as to why you are trying to do this?

Are you using swig to do the javascript port?

Greg

I am currently using the package from Arch Linux's repository, it's 3.7.1.
So I guess this "patch" will be in llvm/lldb 3.8.1?

I am coding bindings for node.js which is basically V8 with an event
loop (libuv). So by the nature of nodejs, having "blocking" could stop
the whole event-loop, that's why I am trying to make WaitForEvent
non-blocking.

I am not using swig to do the port. It's more like directly using the
V8 api which surprisingly isn't that complicated.