palacaze / sigslot

A simple C++14 signal-slots implementation
MIT License
709 stars 97 forks source link

Add slot_count function to retrieve the number of connected slots #13

Closed Dysl3xik closed 4 years ago

palacaze commented 4 years ago

Hi

I am not opposed to this feature, but may I inquire as to why you need it? The number of connected slots would only be meaningful in a single-threaded usage.

Also the proposed implementation is not thread-safe. An actual copy of the cow container is needed to bump the reference count, a reference won't do. And it should be taken under lock.

As an aside, I know that the current COW mechanism is clunky at best. I devised it to avoid costly slot invocations under lock as well as unnecessary copies. It is not thread-safe, only my particular use in conjunction with the mutex lock makes it so. I should probably integrate the mutex to the copy_on_write struct, that would make more sense...

Anyway, something like this should be ok:

size_t slot_count() noexcept {
    auto copy = slot_copy();
    return detail::cow_read(copy).size();
}

slot_copy() is very cheap, it amounts to taking a reference if signal_st<> is used, and a mutex lock plus a pointer copy otherwise.

Also, I would not mind a testcase for this feature.

Dysl3xik commented 4 years ago

The IO in my application notifies consumers about new data using callbacks (now done with this library). Consumers may attach/detach for notifications at will.

Another part of my application is actually logging the raw data coming in and out of the application. To save space I do not bother logging data that nobody is consuming cause it will just bloat the files. To check if data is being used by consumers I look at the number of consumers currently hooked up via this function.

If someone hooks up at the same moment as I check for connections I could get a "wrong" result, but the next moment a packet arrives I will run this check again and see someone is connected and start saving the data again. So to your point "The number of connected slots would only be meaningful in a single-threaded usage." is technically correct, but that is only the case if you need absolute consistent truth.

I suppose I could also work with a function that reports if ANYONE is connected but that is probably the same work as getting the count.

Also how does this function amount to 1 pointer copy? Wouldn't it involve copying the entire vector and every pointer within it? That could be more expensive than a mutex lock, especially since the hold on the mutex will be quite brief.

palacaze commented 4 years ago

The copy_on_write container only performs a copy of the underlying data (the vector of slots) when a write is necessary, so when adding or removing slots to the signal. Signal emission and counting slots are both read-only operations and will not incur a (deep) copy.

Dysl3xik commented 4 years ago

Updated with test!

palacaze commented 4 years ago

Thanks, merged!