mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-15 17:41:45 +00:00
FairMQ: Add functionality to set used message size
This commit is contained in:
committed by
Mohammad Al-Turany
parent
ac4695b215
commit
e5aa85b61d
@@ -1,8 +1,8 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/**
|
||||
@@ -12,11 +12,10 @@
|
||||
* @author D. Klein, A. Rybalchenko, N. Winckler
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "FairMQMessageZMQ.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include <fairmq/Tools.h>
|
||||
#include "FairMQUnmanagedRegionZMQ.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -24,48 +23,60 @@ using namespace std;
|
||||
FairMQ::Transport FairMQMessageZMQ::fTransportType = FairMQ::Transport::ZMQ;
|
||||
|
||||
FairMQMessageZMQ::FairMQMessageZMQ()
|
||||
: fMessage()
|
||||
: fUsedSizeModified(false)
|
||||
, fUsedSize()
|
||||
, fMsg(fair::mq::tools::make_unique<zmq_msg_t>())
|
||||
, fViewMsg(nullptr)
|
||||
{
|
||||
if (zmq_msg_init(&fMessage) != 0)
|
||||
if (zmq_msg_init(fMsg.get()) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
}
|
||||
|
||||
FairMQMessageZMQ::FairMQMessageZMQ(const size_t size)
|
||||
: fMessage()
|
||||
: fUsedSizeModified(false)
|
||||
, fUsedSize(size)
|
||||
, fMsg(fair::mq::tools::make_unique<zmq_msg_t>())
|
||||
, fViewMsg(nullptr)
|
||||
{
|
||||
if (zmq_msg_init_size(&fMessage, size) != 0)
|
||||
if (zmq_msg_init_size(fMsg.get(), size) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message with size, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
}
|
||||
|
||||
FairMQMessageZMQ::FairMQMessageZMQ(void* data, const size_t size, fairmq_free_fn* ffn, void* hint)
|
||||
: fMessage()
|
||||
: fUsedSizeModified(false)
|
||||
, fUsedSize()
|
||||
, fMsg(fair::mq::tools::make_unique<zmq_msg_t>())
|
||||
, fViewMsg(nullptr)
|
||||
{
|
||||
if (zmq_msg_init_data(&fMessage, data, size, ffn, hint) != 0)
|
||||
if (zmq_msg_init_data(fMsg.get(), data, size, ffn, hint) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message with data, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
}
|
||||
|
||||
FairMQMessageZMQ::FairMQMessageZMQ(FairMQUnmanagedRegionPtr& region, void* data, const size_t size)
|
||||
: fMessage()
|
||||
: fUsedSizeModified(false)
|
||||
, fUsedSize()
|
||||
, fMsg(fair::mq::tools::make_unique<zmq_msg_t>())
|
||||
, fViewMsg(nullptr)
|
||||
{
|
||||
// FIXME: make this zero-copy:
|
||||
// simply taking over the provided buffer can casue premature delete, since region could be destroyed before the message is sent out.
|
||||
// Needs lifetime extension for the ZMQ region.
|
||||
if (zmq_msg_init_size(&fMessage, size) != 0)
|
||||
if (zmq_msg_init_size(fMsg.get(), size) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message with size, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
|
||||
memcpy(zmq_msg_data(&fMessage), data, size);
|
||||
memcpy(zmq_msg_data(fMsg.get()), data, size);
|
||||
// call region callback
|
||||
static_cast<FairMQUnmanagedRegionZMQ*>(region.get())->fCallback(data, size);
|
||||
|
||||
// if (zmq_msg_init_data(&fMessage, data, size, [](void*, void*){}, nullptr) != 0)
|
||||
// if (zmq_msg_init_data(fMsg.get(), data, size, [](void*, void*){}, nullptr) != 0)
|
||||
// {
|
||||
// LOG(ERROR) << "failed initializing message with data, reason: " << zmq_strerror(errno);
|
||||
// }
|
||||
@@ -74,7 +85,8 @@ FairMQMessageZMQ::FairMQMessageZMQ(FairMQUnmanagedRegionPtr& region, void* data,
|
||||
void FairMQMessageZMQ::Rebuild()
|
||||
{
|
||||
CloseMessage();
|
||||
if (zmq_msg_init(&fMessage) != 0)
|
||||
fMsg = fair::mq::tools::make_unique<zmq_msg_t>();
|
||||
if (zmq_msg_init(fMsg.get()) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
@@ -83,7 +95,8 @@ void FairMQMessageZMQ::Rebuild()
|
||||
void FairMQMessageZMQ::Rebuild(const size_t size)
|
||||
{
|
||||
CloseMessage();
|
||||
if (zmq_msg_init_size(&fMessage, size) != 0)
|
||||
fMsg = fair::mq::tools::make_unique<zmq_msg_t>();
|
||||
if (zmq_msg_init_size(fMsg.get(), size) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message with size, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
@@ -92,7 +105,8 @@ void FairMQMessageZMQ::Rebuild(const size_t size)
|
||||
void FairMQMessageZMQ::Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint)
|
||||
{
|
||||
CloseMessage();
|
||||
if (zmq_msg_init_data(&fMessage, data, size, ffn, hint) != 0)
|
||||
fMsg = fair::mq::tools::make_unique<zmq_msg_t>();
|
||||
if (zmq_msg_init_data(fMsg.get(), data, size, ffn, hint) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing message with data, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
@@ -100,17 +114,80 @@ void FairMQMessageZMQ::Rebuild(void* data, const size_t size, fairmq_free_fn* ff
|
||||
|
||||
void* FairMQMessageZMQ::GetMessage()
|
||||
{
|
||||
return &fMessage;
|
||||
if (!fViewMsg)
|
||||
{
|
||||
return fMsg.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return fViewMsg.get();
|
||||
}
|
||||
}
|
||||
|
||||
void* FairMQMessageZMQ::GetData()
|
||||
{
|
||||
return zmq_msg_data(&fMessage);
|
||||
if (!fViewMsg)
|
||||
{
|
||||
return zmq_msg_data(fMsg.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
return zmq_msg_data(fViewMsg.get());
|
||||
}
|
||||
}
|
||||
|
||||
size_t FairMQMessageZMQ::GetSize()
|
||||
size_t FairMQMessageZMQ::GetSize() const
|
||||
{
|
||||
return zmq_msg_size(&fMessage);
|
||||
if (fUsedSizeModified)
|
||||
{
|
||||
return fUsedSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
return zmq_msg_size(fMsg.get());
|
||||
}
|
||||
}
|
||||
|
||||
// To emulate shrinking, a new message is created with the new size (ViewMsg), that points to the original buffer with the new size.
|
||||
// Once the "view message" is transfered, the original is destroyed.
|
||||
// Used size is applied only once in ApplyUsedSize, which is called by the socket before sending.
|
||||
// This function just updates the desired size until the actual "resizing" happens.
|
||||
bool FairMQMessageZMQ::SetUsedSize(const size_t size)
|
||||
{
|
||||
if (size <= zmq_msg_size(fMsg.get()))
|
||||
{
|
||||
fUsedSize = size;
|
||||
fUsedSizeModified = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "FairMQMessageZMQ::SetUsedSize: cannot set used size higher than original.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQMessageZMQ::ApplyUsedSize()
|
||||
{
|
||||
// Apply only once (before actual send).
|
||||
// The check is needed because a send could fail and can be reattempted by the user, in this case we do not want to modify buffer again.
|
||||
if (fUsedSizeModified && !fViewMsg)
|
||||
{
|
||||
fViewMsg = fair::mq::tools::make_unique<zmq_msg_t>();
|
||||
void* ptr = zmq_msg_data(fMsg.get());
|
||||
if (zmq_msg_init_data(fViewMsg.get(),
|
||||
ptr,
|
||||
fUsedSize,
|
||||
[](void* /* data */, void* obj)
|
||||
{
|
||||
zmq_msg_close(static_cast<zmq_msg_t*>(obj));
|
||||
delete static_cast<zmq_msg_t*>(obj);
|
||||
},
|
||||
fMsg.release()) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed initializing view message, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQMessageZMQ::SetMessage(void*, const size_t)
|
||||
@@ -123,34 +200,48 @@ FairMQ::Transport FairMQMessageZMQ::GetType() const
|
||||
return fTransportType;
|
||||
}
|
||||
|
||||
void FairMQMessageZMQ::Copy(const unique_ptr<FairMQMessage>& msg)
|
||||
void FairMQMessageZMQ::Copy(const FairMQMessagePtr& msg)
|
||||
{
|
||||
// Shares the message buffer between msg and this fMessage.
|
||||
if (zmq_msg_copy(&fMessage, static_cast<zmq_msg_t*>(msg->GetMessage())) != 0)
|
||||
// Shares the message buffer between msg and this fMsg.
|
||||
if (zmq_msg_copy(fMsg.get(), static_cast<zmq_msg_t*>(msg->GetMessage())) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed copying message, reason: " << zmq_strerror(errno);
|
||||
return;
|
||||
}
|
||||
|
||||
// Alternatively, following code does a hard copy of the message, which allows to modify the original after making a copy, without affecting the new msg.
|
||||
|
||||
// CloseMessage();
|
||||
// size_t size = msg->GetSize();
|
||||
// zmq_msg_init_size(&fMessage, size);
|
||||
// memcpy(zmq_msg_data(&fMessage), msg->GetData(), size);
|
||||
// if the target message has been resized, apply same to this message also
|
||||
if (static_cast<FairMQMessageZMQ*>(msg.get())->fUsedSizeModified)
|
||||
{
|
||||
fUsedSizeModified = true;
|
||||
fUsedSize = static_cast<FairMQMessageZMQ*>(msg.get())->fUsedSize;
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQMessageZMQ::CloseMessage()
|
||||
{
|
||||
if (zmq_msg_close(&fMessage) != 0)
|
||||
if (!fViewMsg)
|
||||
{
|
||||
LOG(ERROR) << "failed closing message, reason: " << zmq_strerror(errno);
|
||||
if (zmq_msg_close(fMsg.get()) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed closing message, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
// reset the message object to allow reuse in Rebuild
|
||||
fMsg.reset(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zmq_msg_close(fViewMsg.get()) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed closing message, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
// reset the message object to allow reuse in Rebuild
|
||||
fViewMsg.reset(nullptr);
|
||||
}
|
||||
fUsedSizeModified = false;
|
||||
fUsedSize = 0;
|
||||
}
|
||||
|
||||
FairMQMessageZMQ::~FairMQMessageZMQ()
|
||||
{
|
||||
if (zmq_msg_close(&fMessage) != 0)
|
||||
{
|
||||
LOG(ERROR) << "failed closing message with data, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
CloseMessage();
|
||||
}
|
||||
|
Reference in New Issue
Block a user