Logo ROOT   6.10/09
Reference Guide
MPSendRecv.cxx
Go to the documentation of this file.
1 /* @(#)root/multiproc:$Id$ */
2 // Author: Enrico Guiraud July 2015
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "MPSendRecv.h"
13 #include "TBufferFile.h"
14 #include "MPCode.h"
15 #include <memory> //unique_ptr
16 
17 //////////////////////////////////////////////////////////////////////////
18 /// Send a message with the specified code on the specified socket.
19 /// This standalone function can be used to send a code
20 /// on a given socket. It does not check whether the socket connection is
21 /// in a valid state. The message code can then be retrieved via MPRecv().\n
22 /// **Note:** only objects the headers of which have been parsed by
23 /// cling can be sent by MPSend(). User-defined types can be made available to
24 /// cling via a call like `gSystem->ProcessLine("#include \"header.h\"")`.
25 /// Pointer types are not supported (with the exception of const char*),
26 /// but the user can simply dereference the pointer and send the
27 /// pointed object instead.\n
28 /// **Note:** for readability, codes should be enumerated as in EMPCode.\n
29 /// \param s a pointer to a valid TSocket. No validity checks are performed\n
30 /// \param code the code to be sent
31 /// \return the number of bytes sent, as per TSocket::SendRaw
32 int MPSend(TSocket *s, unsigned code)
33 {
35  wBuf.WriteUInt(code);
36  wBuf.WriteULong(0);
37  return s->SendRaw(wBuf.Buffer(), wBuf.Length());
38 }
39 
40 
41 //////////////////////////////////////////////////////////////////////////
42 /// Receive message from a socket.
43 /// This standalone function can be used to read a message that
44 /// has been sent via MPSend(). The smart pointer contained in the returned
45 /// ::MPCodeBufPair is null if the message does not contain an object,
46 /// otherwise it points to a TBufferFile.
47 /// To retrieve the object from the buffer different methods must be used
48 /// depending on the type of the object to be read:\n
49 /// * non-pointer built-in types: TBufferFile::operator>> must be used\n
50 /// * c-strings: TBufferFile::ReadString must be used\n
51 /// * class types: TBufferFile::ReadObjectAny must be used\n
52 /// \param s a pointer to a valid TSocket. No validity checks are performed\n
53 /// \return ::MPCodeBufPair, i.e. an std::pair containing message code and (possibly) object
55 {
56  char *rawbuf = new char[sizeof(UInt_t)];
57  //receive message code
58  unsigned nBytes = s->RecvRaw(rawbuf, sizeof(UInt_t));
59  if (nBytes == 0) {
60  return std::make_pair(MPCode::kRecvError, nullptr);
61  }
62  //read message code
63  TBufferFile bufReader(TBuffer::kRead, sizeof(UInt_t), rawbuf, false);
64  unsigned code;
65  bufReader.ReadUInt(code);
66  delete [] rawbuf;
67 
68  //receive object size
69  //ULong_t is sent as 8 bytes irrespective of the size of the type
70  rawbuf = new char[8];
71  s->RecvRaw(rawbuf, 8);
72  bufReader.SetBuffer(rawbuf, 8, false);
73  ULong_t classBufSize;
74  bufReader.ReadULong(classBufSize);
75  delete [] rawbuf;
76 
77  //receive object if needed
78  std::unique_ptr<TBufferFile> objBuf; //defaults to nullptr
79  if (classBufSize != 0) {
80  char *classBuf = new char[classBufSize];
81  s->RecvRaw(classBuf, classBufSize);
82  objBuf.reset(new TBufferFile(TBuffer::kRead, classBufSize, classBuf, true)); //the buffer is deleted by TBuffer's dtor
83  }
84 
85  return std::make_pair(code, std::move(objBuf));
86 }
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket...
Definition: TBufferFile.h:47
MPCodeBufPair MPRecv(TSocket *s)
Receive message from a socket.
Definition: MPSendRecv.cxx:54
int MPSend(TSocket *s, unsigned code)
Send a message with the specified code on the specified socket.
Definition: MPSendRecv.cxx:32
Error while reading from the socket.
Definition: MPCode.h:51
virtual void ReadUInt(UInt_t &i)
Definition: TBufferFile.h:462
virtual void WriteULong(ULong_t l)
Definition: TBufferFile.h:385
Int_t Length() const
Definition: TBuffer.h:94
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
char * Buffer() const
Definition: TBuffer.h:91
virtual void WriteUInt(UInt_t i)
Definition: TBufferFile.h:371
std::pair< unsigned, std::unique_ptr< TBufferFile > > MPCodeBufPair
An std::pair that wraps the code and optional object contained in a message.
Definition: MPSendRecv.h:31
unsigned int UInt_t
Definition: RtypesCore.h:42
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:901
virtual void ReadULong(ULong_t &l)
Definition: TBufferFile.h:476
void SetBuffer(void *buf, UInt_t bufsiz=0, Bool_t adopt=kTRUE, ReAllocCharFun_t reallocfunc=0)
Sets a new buffer in an existing TBuffer object.
Definition: TBuffer.cxx:165