From ef62012c6e83ba4523a84d9d9047166188629222 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Tue, 3 Oct 2017 13:28:14 +0200 Subject: [PATCH] feat(Object): avoid usage of share_from_this --- include/linphone/utils/general.h | 14 ++++-- src/c-wrapper/api/c-call.cpp | 4 +- src/c-wrapper/api/c-chat-room.cpp | 6 +-- src/c-wrapper/internal/c-tools.h | 9 +--- src/chat/basic-chat-room.cpp | 2 +- src/chat/chat-message-p.h | 28 ++++++------ src/chat/chat-message.cpp | 43 +++++++------------ src/chat/chat-message.h | 19 ++++---- src/chat/chat-room.cpp | 9 ++-- src/chat/chat-room.h | 1 + .../encryption-chat-message-modifier.cpp | 4 +- src/chat/real-time-text-chat-room.cpp | 2 +- src/conference/conference.cpp | 2 +- src/conference/local-conference.cpp | 2 +- src/conference/participant.cpp | 8 ++-- src/conference/remote-conference.cpp | 2 +- src/conference/session/call-session.cpp | 4 +- src/conference/session/call-session.h | 2 + src/conference/session/media-session.cpp | 2 +- src/object/object-p.h | 6 ++- src/object/object.cpp | 17 +++++++- src/object/object.h | 27 ++++++++++-- 22 files changed, 121 insertions(+), 92 deletions(-) diff --git a/include/linphone/utils/general.h b/include/linphone/utils/general.h index 515767649..268c9b50a 100644 --- a/include/linphone/utils/general.h +++ b/include/linphone/utils/general.h @@ -103,7 +103,7 @@ class ObjectPrivate; #endif template -inline ClonableObject *getPublicHelper (T *object, ClonableObjectPrivate *context) { +inline ClonableObject *getPublicHelper (T *object, const ClonableObjectPrivate *context) { auto it = object->find(context); L_ASSERT(it != object->end()); return it->second; @@ -117,7 +117,7 @@ inline const ClonableObject *getPublicHelper (const T *object, const ClonableObj } template -inline Object *getPublicHelper (T *object, ObjectPrivate *) { +inline Object *getPublicHelper (T *object, const ObjectPrivate *) { return object; } @@ -127,7 +127,7 @@ inline const Object *getPublicHelper (const T *object, const ObjectPrivate *) { } #define L_DECLARE_PUBLIC(CLASS) \ - inline CLASS * getPublic () { \ + inline CLASS *getPublic () { \ return static_cast(getPublicHelper(mPublic, this)); \ } \ inline const CLASS *getPublic () const { \ @@ -142,6 +142,14 @@ inline const Object *getPublicHelper (const T *object, const ObjectPrivate *) { #define L_D() decltype(std::declval().getPrivate()) const d = getPrivate(); #define L_Q() decltype(std::declval().getPublic()) const q = getPublic(); +#define L_OVERRIDE_SHARED_FROM_THIS(CLASS) \ + inline std::shared_ptr getSharedFromThis () { \ + return std::static_pointer_cast(Object::getSharedFromThis()); \ + } \ + inline std::shared_ptr getSharedFromThis () const { \ + return std::static_pointer_cast(Object::getSharedFromThis()); \ + } + #define L_USE_DEFAULT_SHARE_IMPL(CLASS, PARENT_CLASS) \ CLASS::CLASS (const CLASS &src) : PARENT_CLASS(*src.getPrivate()) {} \ CLASS &CLASS::operator= (const CLASS &src) { \ diff --git a/src/c-wrapper/api/c-call.cpp b/src/c-wrapper/api/c-call.cpp index f7d51ac93..aef5da3ff 100644 --- a/src/c-wrapper/api/c-call.cpp +++ b/src/c-wrapper/api/c-call.cpp @@ -1139,7 +1139,7 @@ void linphone_call_set_user_data (LinphoneCall *call, void *ud) { LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg) { LinphoneCall *call = L_INIT(Call); - L_SET_CPP_PTR_FROM_C_OBJECT(call, make_shared(call, lc, LinphoneCallOutgoing, + L_SET_CPP_PTR_FROM_C_OBJECT(call, LinphonePrivate::ObjectFactory::create(call, lc, LinphoneCallOutgoing, *L_GET_CPP_PTR_FROM_C_OBJECT(from), *L_GET_CPP_PTR_FROM_C_OBJECT(to), cfg, nullptr, L_GET_CPP_PTR_FROM_C_OBJECT(params))); call->currentParamsCache = linphone_call_params_new_for_wrapper(); @@ -1151,7 +1151,7 @@ LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddres LinphoneCall *linphone_call_new_incoming (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op) { LinphoneCall *call = L_INIT(Call); - L_SET_CPP_PTR_FROM_C_OBJECT(call, make_shared(call, lc, LinphoneCallIncoming, + L_SET_CPP_PTR_FROM_C_OBJECT(call, LinphonePrivate::ObjectFactory::create(call, lc, LinphoneCallIncoming, *L_GET_CPP_PTR_FROM_C_OBJECT(from), *L_GET_CPP_PTR_FROM_C_OBJECT(to), nullptr, op, nullptr)); call->currentParamsCache = linphone_call_params_new_for_wrapper(); diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index 3bc39f348..816fbd7c2 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -289,9 +289,9 @@ void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) { LinphoneChatRoom *linphone_chat_room_new (LinphoneCore *core, const LinphoneAddress *addr) { LinphoneChatRoom *cr = L_INIT(ChatRoom); if (linphone_core_realtime_text_enabled(core)) - L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr))); + L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr))); else - L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr))); + L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr))); L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated); L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Created); return cr; @@ -311,7 +311,7 @@ LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, cons from = linphone_core_get_primary_contact(core); LinphonePrivate::Address me(from); LinphoneChatRoom *cr = L_INIT(ChatRoom); - L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared(core, me, L_C_TO_STRING(subject))); + L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create(core, me, L_C_TO_STRING(subject))); L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated); return cr; } diff --git a/src/c-wrapper/internal/c-tools.h b/src/c-wrapper/internal/c-tools.h index 8f4c2749c..030eefe14 100644 --- a/src/c-wrapper/internal/c-tools.h +++ b/src/c-wrapper/internal/c-tools.h @@ -294,7 +294,7 @@ public: return nullptr; try { - return getCBackPtr(std::static_pointer_cast(cppObject->shared_from_this())); + return getCBackPtr(std::static_pointer_cast(cppObject->getSharedFromThis())); } catch (const std::bad_weak_ptr &e) { abort(e.what()); } @@ -545,13 +545,6 @@ LINPHONE_END_NAMESPACE FALSE \ ); -#define L_DECLARE_C_OBJECT_NEW_DEFAULT(C_TYPE, C_NAME) \ - Linphone ## C_TYPE * linphone_ ## C_NAME ## _new() { \ - Linphone ## C_TYPE *object = _linphone_ ## C_TYPE ## _init(); \ - object->cppPtr = std::make_shared(); \ - return object; \ - } - // ----------------------------------------------------------------------------- // Helpers. // ----------------------------------------------------------------------------- diff --git a/src/chat/basic-chat-room.cpp b/src/chat/basic-chat-room.cpp index 2d41a5657..949f02a39 100644 --- a/src/chat/basic-chat-room.cpp +++ b/src/chat/basic-chat-room.cpp @@ -60,7 +60,7 @@ int BasicChatRoom::getNbParticipants () const { list> BasicChatRoom::getParticipants () const { L_D(); list> l; - l.push_back(make_shared(d->peerAddress)); + l.push_back(ObjectFactory::create(d->peerAddress)); return l; } diff --git a/src/chat/chat-message-p.h b/src/chat/chat-message-p.h index 199768d78..1bd7aeee7 100644 --- a/src/chat/chat-message-p.h +++ b/src/chat/chat-message-p.h @@ -37,20 +37,20 @@ public: virtual ~ChatMessagePrivate (); void setChatRoom (std::shared_ptr chatRoom); - + // ----------------------------------------------------------------------------- void setDirection (ChatMessage::Direction dir); void setState(ChatMessage::State state); - + void setTime(time_t time); - + void setIsReadOnly(bool readOnly); - + unsigned int getStorageId() const; void setStorageId(unsigned int id); - + belle_http_request_t *getHttpRequest() const; void setHttpRequest(belle_http_request_t *request); @@ -67,16 +67,16 @@ public: // ----------------------------------------------------------------------------- // Methods only used for C wrapper // ----------------------------------------------------------------------------- - + const std::string& getContentType(); void setContentType(const std::string& contentType); const std::string& getText(); void setText(const std::string& text); - + LinphoneContent * getFileTransferInformation() const; void setFileTransferInformation(LinphoneContent *content); - + // ----------------------------------------------------------------------------- // Need to be public to be called from static C callbacks // ----------------------------------------------------------------------------- @@ -94,11 +94,11 @@ public: void processAuthRequestedUpload(const belle_sip_auth_event *event); void processIoErrorDownload(const belle_sip_io_error_event_t *event); void processResponseFromGetFile(const belle_http_response_event_t *event); - + // ----------------------------------------------------------------------------- - + void sendImdn(ImdnType imdnType, LinphoneReason reason); - + LinphoneReason receive(); void send(); @@ -133,7 +133,7 @@ private: std::string cText = ""; // Used for compatibility with previous C API LinphoneContent *cFileTransferInformation = NULL; - + // ----------------------------------------------------------------------------- std::string createImdnXml(ImdnType imdnType, LinphoneReason reason); @@ -145,10 +145,6 @@ private: void releaseHttpRequest(); void createFileTransferInformationsFromVndGsmaRcsFtHttpXml(); - std::shared_ptr getPublicSharedPtr(); - - // ----------------------------------------------------------------------------- - L_DECLARE_PUBLIC(ChatMessage); }; diff --git a/src/chat/chat-message.cpp b/src/chat/chat-message.cpp index 47f174c33..bbd96d9d7 100644 --- a/src/chat/chat-message.cpp +++ b/src/chat/chat-message.cpp @@ -55,11 +55,6 @@ ChatMessagePrivate::~ChatMessagePrivate () {} // ----------------------------------------------------------------------------- -shared_ptr ChatMessagePrivate::getPublicSharedPtr() { - L_Q(); - return q->getSharedPtr(); -} - void ChatMessagePrivate::setChatRoom (shared_ptr cr) { chatRoom = cr; } @@ -607,7 +602,7 @@ void ChatMessagePrivate::processResponseFromPostFile(const belle_http_response_e _chat_message_file_transfer_on_progress, NULL, NULL, _chat_message_on_send_body, _chat_message_on_send_end, this); if (!fileTransferFilePath.empty()) { - belle_sip_user_body_handler_t *body_handler = (belle_sip_user_body_handler_t *)first_part_bh; + belle_sip_user_body_handler_t *body_handler = (belle_sip_user_body_handler_t *)first_part_bh; // No need to add again the callback for progression, otherwise it will be called twice first_part_bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(fileTransferFilePath.c_str(), NULL, this); linphone_content_set_size(cFileTransferInformation, belle_sip_file_body_handler_get_file_size((belle_sip_file_body_handler_t *)first_part_bh)); @@ -765,8 +760,8 @@ void ChatMessagePrivate::processResponseHeadersFromGetFile(const belle_http_resp body_size = linphone_content_get_size(cFileTransferInformation); } - body_handler = (belle_sip_body_handler_t *)belle_sip_user_body_handler_new(body_size, _chat_message_file_transfer_on_progress, - NULL, _chat_message_on_recv_body, + body_handler = (belle_sip_body_handler_t *)belle_sip_user_body_handler_new(body_size, _chat_message_file_transfer_on_progress, + NULL, _chat_message_on_recv_body, NULL, _chat_message_on_recv_end, this); if (!fileTransferFilePath.empty()) { belle_sip_user_body_handler_t *bh = (belle_sip_user_body_handler_t *)body_handler; @@ -805,7 +800,7 @@ void ChatMessagePrivate::processIoErrorUpload(const belle_sip_io_error_event_t * lError() << "I/O Error during file upload of msg [" << this << "]"; q->updateState(ChatMessage::State::NotDelivered); releaseHttpRequest(); - chatRoom->getPrivate()->removeTransientMessage(q->getSharedPtr()); + chatRoom->getPrivate()->removeTransientMessage(q->getSharedFromThis()); } static void _chat_message_process_auth_requested_upload(void *data, belle_sip_auth_event *event) { @@ -818,7 +813,7 @@ void ChatMessagePrivate::processAuthRequestedUpload(const belle_sip_auth_event * lError() << "Error during file upload: auth requested for msg [" << this << "]"; q->updateState(ChatMessage::State::NotDelivered); releaseHttpRequest(); - chatRoom->getPrivate()->removeTransientMessage(q->getSharedPtr()); + chatRoom->getPrivate()->removeTransientMessage(q->getSharedFromThis()); } static void _chat_message_process_io_error_download(void *data, const belle_sip_io_error_event_t *event) { @@ -983,7 +978,7 @@ LinphoneReason ChatMessagePrivate::receive() { LinphoneReason reason = LinphoneReasonNone; bool store = false; - + // --------------------------------------- // Start of message modification // --------------------------------------- @@ -998,7 +993,7 @@ LinphoneReason ChatMessagePrivate::receive() { retval = ecmm.decode(this); if (retval > 0) { /* Unable to decrypt message */ - chatRoom->getPrivate()->notifyUndecryptableMessageReceived(getPublicSharedPtr()); + chatRoom->getPrivate()->notifyUndecryptableMessageReceived(q->getSharedFromThis()); reason = linphone_error_code_to_reason(retval); q->sendDeliveryNotification(reason); return reason; @@ -1006,7 +1001,7 @@ LinphoneReason ChatMessagePrivate::receive() { MultipartChatMessageModifier mcmm; mcmm.decode(this); - + // --------------------------------------- // End of message modification // --------------------------------------- @@ -1040,7 +1035,7 @@ void ChatMessagePrivate::send() { L_Q(); SalOp *op = salOp; LinphoneCall *call = NULL; - + if (lp_config_get_int(chatRoom->getCore()->config, "sip", "chat_use_call_dialogs", 0) != 0) { call = linphone_core_get_call_by_remote_address(chatRoom->getCore(), chatRoom->getPeerAddress().asString().c_str()); if (call) { @@ -1076,7 +1071,7 @@ void ChatMessagePrivate::send() { op->set_user_pointer(L_GET_C_BACK_PTR(q)); /* If out of call, directly store msg */ linphone_address_unref(peer); } - + // --------------------------------------- // Start of message modification // --------------------------------------- @@ -1090,7 +1085,7 @@ void ChatMessagePrivate::send() { if (!getContentType().empty()) { clearTextContentType = getContentType(); } - + if (contents.size() > 1) { MultipartChatMessageModifier mcmm; mcmm.encode(this); @@ -1098,7 +1093,6 @@ void ChatMessagePrivate::send() { EncryptionChatMessageModifier ecmm; int retval = ecmm.encode(this); - if (retval > 0) { sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", nullptr); q->updateState(ChatMessage::State::NotDelivered); @@ -1110,7 +1104,7 @@ void ChatMessagePrivate::send() { CpimChatMessageModifier ccmm; ccmm.encode(this); } - + // --------------------------------------- // End of message modification // --------------------------------------- @@ -1144,7 +1138,7 @@ void ChatMessagePrivate::send() { /* Might be better fixed by delivering status, but too costly for now */ return; } - + /* If operation failed, we should not change message state */ if (q->isOutgoing()) { setIsReadOnly(true); @@ -1379,9 +1373,8 @@ void ChatMessage::updateState(State state) { d->setState(state); linphone_chat_message_store_state(L_GET_C_BACK_PTR(this)); - if (state == Delivered || state == NotDelivered) { - d->chatRoom->getPrivate()->moveTransientMessageToWeakMessages(static_pointer_cast(shared_from_this())); - } + if (state == Delivered || state == NotDelivered) + d->chatRoom->getPrivate()->moveTransientMessageToWeakMessages(getSharedFromThis()); } void ChatMessage::reSend() { @@ -1392,7 +1385,7 @@ void ChatMessage::reSend() { return; } - d->chatRoom->sendMessage(static_pointer_cast(shared_from_this())); + d->chatRoom->sendMessage(getSharedFromThis()); } void ChatMessage::sendDeliveryNotification(LinphoneReason reason) { @@ -1512,8 +1505,4 @@ int ChatMessage::putCharacter(uint32_t character) { return -1; } -shared_ptr ChatMessage::getSharedPtr() { - return static_pointer_cast(shared_from_this()); -} - LINPHONE_END_NAMESPACE diff --git a/src/chat/chat-message.h b/src/chat/chat-message.h index 9c1c709d3..504549b3a 100644 --- a/src/chat/chat-message.h +++ b/src/chat/chat-message.h @@ -44,12 +44,14 @@ class LINPHONE_PUBLIC ChatMessage : public Object { friend class ChatRoomPrivate; friend class RealTimeTextChatRoomPrivate; -public: +public: + L_OVERRIDE_SHARED_FROM_THIS(ChatMessage); + enum Direction { Incoming, Outgoing }; - + enum State { Idle, InProgress, @@ -100,22 +102,22 @@ public: const std::string& getExternalBodyUrl() const; void setExternalBodyUrl(const std::string &url); - + time_t getTime() const; bool isSecured() const; void setIsSecured(bool isSecured); State getState() const; - + const std::string& getId() const; void setId(const std::string&); bool isRead() const; - + const std::string& getAppdata() const; void setAppdata(const std::string &appData); - + const Address& getFromAddress() const; void setFromAddress(Address from); void setFromAddress(const std::string& from); @@ -131,9 +133,9 @@ public: void setIsToBeStored(bool store); const LinphoneErrorInfo * getErrorInfo() const; - + bool isReadOnly() const; - + std::list > getContents() const; void addContent(const std::shared_ptr &content); void removeContent(const std::shared_ptr &content); @@ -143,7 +145,6 @@ public: void removeCustomHeader(const std::string &headerName); protected: - std::shared_ptr getSharedPtr(); explicit ChatMessage(ChatMessagePrivate &p); private: diff --git a/src/chat/chat-room.cpp b/src/chat/chat-room.cpp index c6b9e7c6e..ab5aa3116 100644 --- a/src/chat/chat-room.cpp +++ b/src/chat/chat-room.cpp @@ -211,7 +211,7 @@ void ChatRoomPrivate::sendIsComposingNotification () { shared_ptr msg = q->createMessage(); msg->setFromAddress(identity); msg->setToAddress(peerAddress.asString()); - + shared_ptr content = make_shared(); content->setContentType("application/im-iscomposing+xml"); content->setBody(payload); @@ -277,7 +277,7 @@ int ChatRoomPrivate::createChatMessageFromDb (int argc, char **argv, char **colN } if (argv[13]) { content->setContentType(argv[13]); - } + } Address peer(peerAddress.asString()); if (atoi(argv[3]) == ChatMessage::Direction::Incoming) { @@ -555,7 +555,6 @@ shared_ptr ChatRoom::createFileTransferMessage (const LinphoneConte chatMessage->setToAddress(d->peerAddress); chatMessage->setFromAddress(linphone_core_get_identity(d->core)); - chatMessage->getPrivate()->setDirection(ChatMessage::Direction::Outgoing); chatMessage->getPrivate()->setFileTransferInformation(linphone_content_copy(initialContent)); @@ -578,7 +577,7 @@ shared_ptr ChatRoom::createMessage (const string &message) { } shared_ptr ChatRoom::createMessage () { - shared_ptr chatMessage = make_shared(static_pointer_cast(shared_from_this())); + shared_ptr chatMessage = ObjectFactory::create(getSharedFromThis()); chatMessage->getPrivate()->setTime(ms_time(0)); return chatMessage; } @@ -742,7 +741,7 @@ void ChatRoom::sendMessage (shared_ptr msg) { d->addTransientMessage(msg); /* Store the message so that even if the upload is stopped, it can be done again */ d->storeOrUpdateMessage(msg); - + msg->getPrivate()->setState(ChatMessage::State::InProgress); } else { return; diff --git a/src/chat/chat-room.h b/src/chat/chat-room.h index e9d2ea018..781b3a303 100644 --- a/src/chat/chat-room.h +++ b/src/chat/chat-room.h @@ -44,6 +44,7 @@ class LINPHONE_PUBLIC ChatRoom : public Object, public ConferenceInterface { public: L_DECLARE_ENUM(State, L_ENUM_VALUES_CHAT_ROOM_STATE); + L_OVERRIDE_SHARED_FROM_THIS(ChatRoom); ChatRoom (LinphoneCore *core); virtual ~ChatRoom () = default; diff --git a/src/chat/modifier/encryption-chat-message-modifier.cpp b/src/chat/modifier/encryption-chat-message-modifier.cpp index 0949724b4..af5b24c91 100644 --- a/src/chat/modifier/encryption-chat-message-modifier.cpp +++ b/src/chat/modifier/encryption-chat-message-modifier.cpp @@ -40,7 +40,7 @@ int EncryptionChatMessageModifier::encode (ChatMessagePrivate *messagePrivate) { LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs); if (cbProcessOutgoingMessage) { - retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublicSharedPtr())); + retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublic()->getSharedFromThis())); if (retval == 0) { messagePrivate->isSecured = true; } @@ -56,7 +56,7 @@ int EncryptionChatMessageModifier::decode (ChatMessagePrivate *messagePrivate) { LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsIncomingMessageCb cbProcessIncomingMessage = linphone_im_encryption_engine_cbs_get_process_incoming_message(imeeCbs); if (cbProcessIncomingMessage) { - retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublicSharedPtr())); + retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublic()->getSharedFromThis())); if (retval == 0) { messagePrivate->isSecured = true; } diff --git a/src/chat/real-time-text-chat-room.cpp b/src/chat/real-time-text-chat-room.cpp index 885b98e33..321a0fe56 100644 --- a/src/chat/real-time-text-chat-room.cpp +++ b/src/chat/real-time-text-chat-room.cpp @@ -156,7 +156,7 @@ int RealTimeTextChatRoom::getNbParticipants () const { list> RealTimeTextChatRoom::getParticipants () const { L_D(); list> l; - l.push_back(make_shared(d->peerAddress)); + l.push_back(ObjectFactory::create(d->peerAddress)); return l; } diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp index 818273165..2ae674663 100644 --- a/src/conference/conference.cpp +++ b/src/conference/conference.cpp @@ -29,7 +29,7 @@ LINPHONE_BEGIN_NAMESPACE Conference::Conference (LinphoneCore *core, const Address &myAddress, CallListener *listener) : core(core), callListener(listener) { - me = make_shared(myAddress); + me = ObjectFactory::create(myAddress); } // ----------------------------------------------------------------------------- diff --git a/src/conference/local-conference.cpp b/src/conference/local-conference.cpp index 1de626295..baad5dda5 100644 --- a/src/conference/local-conference.cpp +++ b/src/conference/local-conference.cpp @@ -42,7 +42,7 @@ shared_ptr LocalConference::addParticipant (const Address &addr, co shared_ptr participant = findParticipant(addr); if (participant) return participant; - participant = make_shared(addr); + participant = ObjectFactory::create(addr); participant->getPrivate()->createSession(*this, params, hasMedia, this); participants.push_back(participant); if (!activeParticipant) diff --git a/src/conference/participant.cpp b/src/conference/participant.cpp index 31a25000d..eea9b7f31 100644 --- a/src/conference/participant.cpp +++ b/src/conference/participant.cpp @@ -29,11 +29,13 @@ LINPHONE_BEGIN_NAMESPACE // ============================================================================= -shared_ptr ParticipantPrivate::createSession (const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener) { +shared_ptr ParticipantPrivate::createSession ( + const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener +) { if (hasMedia && (!params || dynamic_cast(params))) { - session = make_shared(conference, params, listener); + session = ObjectFactory::create(conference, params, listener); } else { - session = make_shared(conference, params, listener); + session = ObjectFactory::create(conference, params, listener); } return session; } diff --git a/src/conference/remote-conference.cpp b/src/conference/remote-conference.cpp index 1f38c4d13..d3e1b2f04 100644 --- a/src/conference/remote-conference.cpp +++ b/src/conference/remote-conference.cpp @@ -43,7 +43,7 @@ shared_ptr RemoteConference::addParticipant (const Address &addr, c shared_ptr participant = findParticipant(addr); if (participant) return participant; - participant = make_shared(addr); + participant = ObjectFactory::create(addr); participant->getPrivate()->createSession(*this, params, hasMedia, this); participants.push_back(participant); if (!activeParticipant) diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 2397cbe6b..40347a8f5 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -839,7 +839,7 @@ void CallSession::startIncomingNotification () { if (d->listener) d->listener->onCallSessionAccepted(*this); /* Prevent the CallSession from being destroyed while we are notifying, if the user declines within the state callback */ - shared_ptr ref = static_pointer_cast(shared_from_this()); + shared_ptr ref = getSharedFromThis(); #if 0 call->bg_task_id=sal_begin_background_task("liblinphone call notification", NULL, NULL); #endif @@ -883,7 +883,7 @@ int CallSession::startInvite (const Address *destination, const string &subject) } char *from = linphone_address_as_string(d->log->from); /* Take a ref because sal_call() may destroy the CallSession if no SIP transport is available */ - shared_ptr ref = static_pointer_cast(shared_from_this()); + shared_ptr ref = getSharedFromThis(); int result = d->op->call(from, destinationStr.c_str(), subject.empty() ? nullptr : subject.c_str()); ms_free(from); if (result < 0) { diff --git a/src/conference/session/call-session.h b/src/conference/session/call-session.h index 52ae7e1d3..2495dab34 100644 --- a/src/conference/session/call-session.h +++ b/src/conference/session/call-session.h @@ -38,6 +38,8 @@ class LINPHONE_PUBLIC CallSession : public Object { friend class ClientGroupChatRoom; public: + L_OVERRIDE_SHARED_FROM_THIS(CallSession); + CallSession (const Conference &conference, const CallSessionParams *params, CallSessionListener *listener); LinphoneStatus accept (const CallSessionParams *csp = nullptr); diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 505821151..c19d55098 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -609,7 +609,7 @@ float MediaSessionPrivate::aggregateQualityRatings (float audioRating, float vid void MediaSessionPrivate::setState (LinphoneCallState newState, const string &message) { L_Q(); /* Take a ref on the session otherwise it might get destroyed during the call to setState */ - shared_ptr session = static_pointer_cast(q->shared_from_this()); + shared_ptr session = q->getSharedFromThis(); CallSessionPrivate::setState(newState, message); updateReportingCallState(); } diff --git a/src/object/object-p.h b/src/object/object-p.h index 0b3cf57a2..fe0d42c25 100644 --- a/src/object/object-p.h +++ b/src/object/object-p.h @@ -19,6 +19,7 @@ #ifndef _OBJECT_P_H_ #define _OBJECT_P_H_ +#include #include #include "variant/variant.h" @@ -28,14 +29,17 @@ LINPHONE_BEGIN_NAMESPACE class ObjectPrivate { + friend class ObjectFactory; + public: virtual ~ObjectPrivate () = default; protected: - Object *mPublic = nullptr; + Object *mPublic; private: std::unordered_map properties; + std::weak_ptr weak; L_DECLARE_PUBLIC(Object); }; diff --git a/src/object/object.cpp b/src/object/object.cpp index 01457e82d..4d83a7b54 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -30,8 +30,21 @@ Object::~Object () { delete mPrivate; } -Object::Object (ObjectPrivate &p) : mPrivate(&p) { - mPrivate->mPublic = this; +Object::Object (ObjectPrivate &p) : mPrivate(&p) {} + +shared_ptr Object::getSharedFromThis () { + return mPrivate->weak.lock(); +} + +shared_ptr Object::getSharedFromThis () const { + return mPrivate->weak.lock(); +} + +void ObjectFactory::setPublic (const shared_ptr &object) { + L_ASSERT(object); + ObjectPrivate *d = object->getPrivate(); + d->mPublic = object.get(); + d->weak = object; } LINPHONE_END_NAMESPACE diff --git a/src/object/object.h b/src/object/object.h index ede98e862..cf1afddea 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -27,15 +27,18 @@ LINPHONE_BEGIN_NAMESPACE -class LINPHONE_PUBLIC Object : - public std::enable_shared_from_this, - public PropertyContainer { +class LINPHONE_PUBLIC Object : public PropertyContainer { + friend class ObjectFactory; + public: virtual ~Object (); protected: explicit Object (ObjectPrivate &p); + std::shared_ptr getSharedFromThis (); + std::shared_ptr getSharedFromThis () const; + ObjectPrivate *mPrivate = nullptr; private: @@ -43,6 +46,24 @@ private: L_DISABLE_COPY(Object); }; +class ObjectFactory { +public: + template + static inline std::shared_ptr create (Args &&...args) { + static_assert(std::is_base_of::value, "Not an object."); + std::shared_ptr object = std::make_shared(args...); + setPublic(object); + return object; + } + +private: + ObjectFactory () = delete; + + static void setPublic (const std::shared_ptr &object); + + L_DISABLE_COPY(ObjectFactory); +}; + LINPHONE_END_NAMESPACE #endif // ifndef _OBJECT_H_