Skip to content

Commit

Permalink
Merge pull request JosephP91#104 from sergey-shambir/noncopyable_multi
Browse files Browse the repository at this point in the history
  • Loading branch information
JosephP91 authored Jun 1, 2017
2 parents 59623ae + f4928ff commit 863eb0f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 49 deletions.
26 changes: 13 additions & 13 deletions include/curl_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,17 +212,15 @@ namespace curl {
* to initialize the entire curl environment using custom
* options.
*/
explicit curl_multi(const long);
explicit curl_multi(const long globalOptions);
/**
* Copy constructor to perform a correct copy of the curl
* handler and attributes.
* Move constructor which moves internal data to another object.
*/
curl_multi(const curl_multi &);
curl_multi(curl_multi&&);
/**
* Assignment operator. Let's apply the rule of three to
* avoid strange situations!
* Move assignment operator which moves internal data to another object.
*/
curl_multi &operator=(const curl_multi &);
curl_multi& operator=(curl_multi&&);
/**
* Destructor to deallocate all the resources using
* libcurl.
Expand Down Expand Up @@ -318,9 +316,16 @@ namespace curl {
*/
CURLM *get_curl() const;
private:
struct milti_deleter
{
void operator()(CURLM* ptr) const;
};

using multi_ptr = std::unique_ptr<CURLM, milti_deleter>;

int message_queued;
int active_transfers;
CURLM *curl;
multi_ptr curl;
};

// Implementation of add method
Expand Down Expand Up @@ -370,11 +375,6 @@ namespace curl {
inline const void *curl_multi::curl_message::get_other() const {
return this->whatever;
}

// Implementation of get_curl method.
inline CURLM *curl_multi::get_curl() const {
return this->curl;
}
}

#undef CURLCPP_DEFINE_OPTION
Expand Down
76 changes: 40 additions & 36 deletions src/curl_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,57 +11,56 @@ using curl::curl_easy;
using std::vector;
using std::unique_ptr;

// Implementation of constructor.
curl_multi::curl_multi() : curl_interface() {
this->curl = curl_multi_init();
void curl_multi::milti_deleter::operator()(CURLM* ptr) const
{
curl_multi_cleanup(ptr);
}

curl_multi::curl_multi() : curl_multi(CURL_GLOBAL_ALL) {
}

curl_multi::curl_multi(const long flag)
: curl_interface(flag),
curl(curl_multi_init()) {
if (this->curl == nullptr) {
throw curl_multi_exception("Null pointer intercepted",__FUNCTION__);
throw curl_multi_exception("Null pointer intercepted", __FUNCTION__);
}
this->active_transfers = 0;
this->message_queued = 0;
}

// Implementation of overloaded constructor.
curl_multi::curl_multi(const long flag) : curl_interface(flag) {
curl_multi();
curl_multi::curl_multi(curl_multi&& other)
: curl_interface(std::forward<curl_interface>(other)),
curl(std::move(other.curl)),
active_transfers(other.active_transfers),
message_queued(other.message_queued) {
}

// Implementation of copy constructor to respect the rule of three.
curl_multi::curl_multi(const curl_multi &multi)
: curl_interface(),
message_queued(multi.message_queued),
active_transfers(multi.active_transfers) {
this->curl = curl_multi_init();
if (this->curl == nullptr) {
throw curl_multi_exception("Null pointer intercepted",__FUNCTION__);
curl_multi &curl_multi::operator=(curl_multi&& other) {
if (this != &other) {
curl = std::move(other.curl);
active_transfers = other.active_transfers;
message_queued = other.message_queued;
}
}

// Implementation of assignment operator to perform deep copy.
curl_multi &curl_multi::operator=(const curl_multi &multi) {
if (this == &multi) {
return *this;
}
curl_multi();
return *this;
}

// Implementation of destructor.
curl_multi::~curl_multi() NOEXCEPT{
curl_multi_cleanup(this->curl);
curl_multi::~curl_multi() NOEXCEPT
{
}

// Implementation of add method for easy handlers.
void curl_multi::add(const curl_easy &easy) {
const CURLMcode code = curl_multi_add_handle(this->curl,easy.get_curl());
const CURLMcode code = curl_multi_add_handle(this->curl.get(),easy.get_curl());
if (code != CURLM_OK) {
throw curl_multi_exception(code,__FUNCTION__);
}
}

// Implementation of remove for easy handlers.
void curl_multi::remove(const curl_easy &easy) {
const CURLMcode code = curl_multi_remove_handle(this->curl,easy.get_curl());
const CURLMcode code = curl_multi_remove_handle(this->curl.get(),easy.get_curl());
if (code != CURLM_OK) {
throw curl_multi_exception(code,__FUNCTION__);
}
Expand All @@ -71,7 +70,7 @@ void curl_multi::remove(const curl_easy &easy) {
vector<unique_ptr<curl_multi::curl_message>> curl_multi::get_info() {
vector<unique_ptr<curl_multi::curl_message>> infos;
CURLMsg *message = nullptr;
while ((message = curl_multi_info_read(this->curl,&this->message_queued))) {
while ((message = curl_multi_info_read(this->curl.get(),&this->message_queued))) {
infos.push_back(unique_ptr<curl_multi::curl_message>(new curl_multi::curl_message(message)));
}
return infos;
Expand All @@ -80,7 +79,7 @@ vector<unique_ptr<curl_multi::curl_message>> curl_multi::get_info() {
// Implementation of overloaded get_info method.
unique_ptr<curl_multi::curl_message> curl_multi::get_info(const curl_easy &easy) {
CURLMsg *message = nullptr;
while ((message = curl_multi_info_read(this->curl,&this->message_queued))) {
while ((message = curl_multi_info_read(this->curl.get(),&this->message_queued))) {
if (message->easy_handle == easy.get_curl()) {
unique_ptr<curl_multi::curl_message> ptr{new curl_multi::curl_message(message)};
return ptr;
Expand All @@ -92,7 +91,7 @@ unique_ptr<curl_multi::curl_message> curl_multi::get_info(const curl_easy &easy)
// Implementation of is_finished method.
bool curl_multi::is_finished(const curl_easy &easy) {
CURLMsg *message = nullptr;
while ((message = curl_multi_info_read(this->curl,&this->message_queued))) {
while ((message = curl_multi_info_read(this->curl.get(),&this->message_queued))) {
if (message->easy_handle == easy.get_curl() and message->msg == CURLMSG_DONE) {
return true;
}
Expand All @@ -102,7 +101,7 @@ bool curl_multi::is_finished(const curl_easy &easy) {

// Implementation of perform method.
bool curl_multi::perform() {
const CURLMcode code = curl_multi_perform(this->curl,&this->active_transfers);
const CURLMcode code = curl_multi_perform(this->curl.get(),&this->active_transfers);
if (code == CURLM_CALL_MULTI_PERFORM) {
return false;
}
Expand All @@ -114,7 +113,7 @@ bool curl_multi::perform() {

// Implementation of socket_action method.
bool curl_multi::socket_action(const curl_socket_t sockfd, const int ev_bitmask) {
const CURLMcode code = curl_multi_socket_action(this->curl,sockfd,ev_bitmask,&this->active_transfers);
const CURLMcode code = curl_multi_socket_action(this->curl.get(),sockfd,ev_bitmask,&this->active_transfers);
if (code == CURLM_CALL_MULTI_PERFORM) {
return false;
}
Expand All @@ -126,31 +125,31 @@ bool curl_multi::socket_action(const curl_socket_t sockfd, const int ev_bitmask)

// Implementation of set_fd method.
void curl_multi::set_descriptors(fd_set *read, fd_set *write, fd_set *exec, int *max_fd) {
const CURLMcode code = curl_multi_fdset(this->curl,read,write,exec,max_fd);
const CURLMcode code = curl_multi_fdset(this->curl.get(),read,write,exec,max_fd);
if (code != CURLM_OK) {
throw curl_multi_exception(code,__FUNCTION__);
}
}

// Implementation of wait method.
void curl_multi::wait(struct curl_waitfd extra_fds[], const unsigned int extra_nfds, const int timeout_ms, int *numfds) {
const CURLMcode code = curl_multi_wait(this->curl,extra_fds,extra_nfds,timeout_ms,numfds);
const CURLMcode code = curl_multi_wait(this->curl.get(),extra_fds,extra_nfds,timeout_ms,numfds);
if (code != CURLM_OK) {
throw curl_multi_exception(code,__FUNCTION__);
}
}

// Implementation of assign method.
void curl_multi::assign(const curl_socket_t sockfd, void *sockptr) {
const CURLMcode code = curl_multi_assign(this->curl,sockfd,sockptr);
const CURLMcode code = curl_multi_assign(this->curl.get(),sockfd,sockptr);
if (code != CURLM_OK) {
throw curl_multi_exception(code,__FUNCTION__);
}
}

// Implementation of timeout method.
void curl_multi::timeout(long *timeout) {
const CURLMcode code = curl_multi_timeout(this->curl,timeout);
const CURLMcode code = curl_multi_timeout(this->curl.get(),timeout);
if (code != CURLM_OK) {
throw curl_multi_exception(code,__FUNCTION__);
}
Expand All @@ -161,3 +160,8 @@ curl_multi::curl_message::curl_message(const CURLMsg *msg) :
message(msg->msg), whatever(msg->data.whatever), code(msg->data.result) {
// ... nothing to do here ...
}

// Implementation of get_curl method.
CURLM *curl_multi::get_curl() const {
return this->curl.get();
}

0 comments on commit 863eb0f

Please sign in to comment.