-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Small code review like avoiding redundant objects copy. #1247
Conversation
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 like this PR a lot. Thanks a lot! My only concern is the use of std::move() for paths that don't need optimization yet, but it's just a matter of simplicity and trying to avoid future bugs. I'd like to know your opinion.
@@ -737,7 +737,7 @@ void WebRtcConnection::syncWrite(std::shared_ptr<DataPacket> packet) { | |||
} | |||
|
|||
void WebRtcConnection::setTransport(std::shared_ptr<Transport> transport) { // Only for Testing purposes | |||
video_transport_ = transport; | |||
video_transport_ = std::move(transport); |
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.
In general I'm a bit reluctant to use std::move() in places that aren't hot paths because it's too easy to introduce bugs if we try to use the pointer later in the code, am I right?
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.
Coping the shared pointer basically causes reference counter increment, function move instead doesn't affect reference counter at all because it simply transfers its ownership to another object.
Please consider the following code:
#include <iostream>
#include <memory>
class A
{
public:
std::string some_usefull_string;
};
void do_stuff_with_copied_shared_ptr(std::shared_ptr<A> ptr)
{
std::cout << "before coping use_count is " << ptr.use_count() << std::endl;
std::shared_ptr<A> local_ptr = ptr;
std::cout << "after coping use_count is " << ptr.use_count() << std::endl;
}
void do_stuff_with_moved_shared_ptr(std::shared_ptr<A> ptr)
{
std::cout << "before moving use_count is " << ptr.use_count() << std::endl;
std::shared_ptr<A> local_ptr = std::move(ptr);
std::cout << "after moving ptr use_count is " << ptr.use_count() << std::endl;
if(!ptr)
std::cout << "because ptr is not valid any more" << std::endl;
if(local_ptr)
std::cout << "but local_ptr is valid" << std::endl;
std::cout << "and local_ptr use_count is " << local_ptr.use_count() << std::endl;
}
int main()
{
std::shared_ptr<A> ptr = std::make_shared<A>();
std::cout << "after construction use_count is " << ptr.use_count() << std::endl;
do_stuff_with_copied_shared_ptr(ptr);
do_stuff_with_moved_shared_ptr(ptr);
std::cout << "before leaving use_count is " << ptr.use_count() << std::endl;
return 0;
}
Obviously std::move() invalidates the object passed (ptr in this case), so you should be aware of this, but you can use "local_ptr" which is always valid. And this is the best practice in small functions like setters because the reference counter is atomic and changing it requires more time then a for standard variable. It's just a little performance improvement, so feel you free to use it in the way you like. :)
For more info please take a look at this topic on stackoverflow.
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.
Yes, I know how it works, my point is whether the possibility to introduce bugs if we use an invalidated pointer when updating this code by accident worths the code optimization. We always have to consider that specially in OS projects we can receive PRs updating this code and it could be difficult to detect this kind of issues during a review. But I also see that setters are a reasonable place where we can use std::move.
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 perfectly agree. So if it's OK for you, in my PRs I'll move(shared_ptr) only in one line setters.
@@ -279,10 +279,10 @@ void DtlsTransport::onHandshakeCompleted(DtlsSocketContext *ctx, std::string cli | |||
boost::mutex::scoped_lock lock(sessionMutex_); | |||
std::string temp; | |||
|
|||
if (rtp_timeout_checker_.get() != NULL) { | |||
if (rtp_timeout_checker_) { |
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.
👍
ELOG_WARN("%s message: Handshake failed, transportName:%s, openSSLerror: %s", | ||
toLog(), transport_name.c_str(), error.c_str()); | ||
running_ = false; | ||
updateTransportState(TRANSPORT_FAILED); | ||
} | ||
|
||
std::string DtlsTransport::getMyFingerprint() { | ||
std::string DtlsTransport::getMyFingerprint() const { |
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.
👍
@@ -316,14 +316,14 @@ void DtlsTransport::onHandshakeCompleted(DtlsSocketContext *ctx, std::string cli | |||
} | |||
} | |||
|
|||
void DtlsTransport::onHandshakeFailed(DtlsSocketContext *ctx, const std::string error) { | |||
void DtlsTransport::onHandshakeFailed(DtlsSocketContext *ctx, const std::string& error) { |
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.
👍
pipeline_->addFront(PacketCodecParser()); | ||
|
||
pipeline_->addFront(PacketWriter(this)); | ||
pipeline_->addFront(std::make_shared<PacketReader>(this)); |
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.
👍
@@ -455,7 +455,7 @@ std::string WebRtcConnection::getJSONCandidate(const std::string& mid, const std | |||
|
|||
std::ostringstream theString; | |||
theString << "{"; | |||
for (std::map<std::string, std::string>::iterator it = object.begin(); it != object.end(); ++it) { | |||
for (std::map<std::string, std::string>::const_iterator it = object.begin(); it != object.end(); ++it) { |
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.
👍
mSocket->getMyCertFingerprint(fprint); | ||
return std::string(fprint, strlen(fprint)); | ||
return std::string(fprint); |
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.
👍
@@ -35,21 +35,21 @@ class LogContext { | |||
LogContext() : context_log_{""} { | |||
} | |||
|
|||
virtual ~LogContext() {} | |||
virtual ~LogContext() = default; |
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.
👍
@@ -316,10 +316,10 @@ void ExternalOutput::initializePipeline() { | |||
pipeline_->addService(quality_manager_); | |||
pipeline_->addService(stats_); | |||
|
|||
pipeline_->addFront(LayerBitrateCalculationHandler()); | |||
pipeline_->addFront(QualityFilterHandler()); | |||
pipeline_->addFront(std::make_shared<LayerBitrateCalculationHandler>()); |
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.
👍
btw, tests failed but it seems like docker registry could have failed, can you rebuild it to check if tests are green? EDIT: I fixed the issue with CircleCI in another PR and I merged it here to see if it now passes all the tests |
PARTIAL CODE REVIEW
Basically the main change is adding Handlers to the pipeline as "make_shared" pointer.