Commit 366cc693 authored by Frank B. Brokken's avatar Frank B. Brokken

removed the pimpl-data from Process

parent 2dab614b
......@@ -68,7 +68,6 @@ osharedstream
pattern
pipe
process
processdata
processenums
ptriter
qpbufbase
......
......@@ -152,7 +152,13 @@ bobcat (5.00.00)
* OMutexStream:
new class offering mutex protected ostream operations.
* ProcessData:
Internal class previously used by Process to store the Pimpl-data. Now
discontinued.
* Process:
- The class was redesigned so the pimpl idiom (implemented in bobcat
3.19.00) is no longer required.
- The mode parameter defined for the second through fourth constructor
must be a Process::IOMode value. The same applies to the function
call operator previously accespting a size_t argument.
......@@ -185,6 +191,7 @@ bobcat (5.00.00)
* Fixed flaw in Log's FBB::fnl handling
-- Frank B. Brokken <f.b.brokken@rug.nl> Fri, 26 Apr 2019 15:30:50 +0200
bobcat (4.09.00)
......
......@@ -16,54 +16,85 @@ manpagesection(MANIPULATORS)
itb(FBB::center) defined in tt(bobcat/align)
This manipulator can be specified when constructing an bf(FBB::Align)
object to indicate that a table column should center its contents.
itb(FBB::decindent) defined in tt(bobcat/indent)
This manipulator reduces the indentation level.
itb(FBB::def)
defined in tt(bobcat/table)
This manipulator `completes' a bf(Table) object to a full rectangular
object. It can be inserted into a bf(Table) object.
itb(FBB::eoi)
defined in tt(bobcat/eoi)
Inserting this manipulator indicates `end of input' of streams
initialized with classes derived from tt(std::streambuf) receiving
information from external sources. Examples (non-exhaustive list) are
found in the classes bf(EncryptBuf, HMacBuf, OfdBuf, Process). Usually
classes supporting the tt(eoi) manipulator also offer a member tt(eoi)
performing the same actions as the manipulator.
itb(FBB::err) defined in tt(bobcat/msg)
Generates an error message.
itb(FBB::errnodescr) defined in tt(bobcat/exception)
Inserts the textual description of the current tt(::errno) value
into the tt(ostream) into which the manipulator is inserted. If
tt(errno == 0) nothing is inserted.
itb(FBB::fatal) defined in tt(bobcat/msg)
Generates a fatal message, followed by an bf(Exception)bf((1)) exception.
Generates a fatal message, followed by an bf(Exception)bf((1))
exception.
itb(FBB::fs) defined in tt(bobcat/tablebuf)
Starts the definition of the next element in a table.
itb(FBB::info) defined in tt(bobcat/msg)
Generates an informational message.
itb(FBB::incindent) defined in tt(bobcat/indent)
This manipulator will increment the indentation level.
itb(FBB::indent) defined in tt(bobcat/indent)
This manipulator inserts the currently defined number of indentation
blanks into an tt(ostream).
itb(FBB::indentdec) defined in tt(bobcat/indent)
This manipulator will insert, then reduce the indentation level.
itb(FBB::indentinc) defined in tt(bobcat/indent)
This manipulator will insert, then increment the indentation level.
itb(FBB::lm) defined in tt(bobcat/ofoldbuf)
This manipulator sets the left margin of bf(FBB::OFoldStream) objects.
itb(FBB::mlm) defined in tt(bobcat/ofoldbuf)
This manipulator modifies (alters) the left margin of
bf(FBB::OFoldStream) objects.
itb(FBB::nlindent) defined in tt(bobcat/indent)
This manipulator will insert a newline, then indent.
itb(FBB::rs) defined in tt(bobcat/tablebuf)
Starts the definition of the next row in a table.
itb(FBB::spool) defined in tt(bobcat/msg)
Generates a (partial) informational message.
itb(FBB::errnodescr) defined in tt(bobcat/exception)
Inserts the textual description of the current tt(::errno) value
into the tt(ostream) into which the manipulator is inserted. If
tt(errno == 0) nothing is inserted.
itb(FBB::warning) defined in tt(bobcat/msg)
Generates a warning message.
)
manpageseealso()
bf(bobcat)(7), bf(columnwidth)(3bobcat), bf(equalwidth)(3bobcat),
bf(indent)(3bobcat), bf(lm)(3bobcat),
bf(bobcat)(7), bf(columnwidth)(3bobcat), bf(eoi)(3bobcat),
bf(equalwidth)(3bobcat), bf(indent)(3bobcat), bf(lm)(3bobcat),
bf(mlm)(3bobcat), bf(msg)(3bobcat), bf(table)(3bobcat)
manpagebugs()
None Reported.
includefile(include/trailer)
......@@ -287,12 +287,13 @@ manpagesection(OVERLOADED OPERATORS)
itemization(
itb(Process &operator<<(Type value))
This operator inserts tt(value) into the child's standard
input stream. I.e., the child process reads tt(value) from its standard
input. A value of any type that can be inserted into an tt(ostream) can be
inserted into a tt(Process) object. Nothing happens if the member is used when
the child process has terminated. The behavior of this operator is undefined
unless tt(IOMode CIN) was specified.
This operator inserts tt(value) into the child's standard input
stream. I.e., the child process reads tt(value) from its standard input. A
value of any type that can be inserted into an tt(ostream) can be inserted
into a tt(Process) object. Nothing happens if the member is used when the
child process has terminated. Manipulators like tt(std::endl) are also
supported. The behavior of this operator is undefined unless tt(IOMode CIN)
was specified.
itb(Process &operator>>(Type value))
This operator extracts tt(value) from the child's standard output
......
#include "process.ih"
size_t Process::bufSize() const
{
return d_data->d_bufSize;
}
inline size_t Process::bufSize() const
{
return d_bufSize;
}
......@@ -4,6 +4,7 @@ Process::~Process()
{
stop();
delete d_data; // delete additional data
// delete d_data; // delete additional data
Signal::instance().remove(SIGCHLD, *this);
}
#include <iostream>
#include "../../processenums/processenums"
#include "../../processdata/processdata.decl"
#include "../process"
using namespace std;
......@@ -22,7 +21,7 @@ int main()
if (not getline(cin, line))
return 0;
process << line << endl; // to /bin/cat
process << line << endl; // to /bin/cat
line.clear();
if (not getline(process, line)) // from /bin/cat
......
#include <iostream>
#include "../../processenums/processenums"
#include "../../processdata/processdata.decl"
#include "../process"
using namespace std;
......@@ -19,9 +18,3 @@ int main()
p3 << cin.rdbuf() << eoi;
}
......@@ -2,7 +2,6 @@
#include <iostream>
#include "../../processenums/processenums"
#include "../../processdata/processdata.decl"
#include "../process"
using namespace std;
......
......@@ -5,7 +5,7 @@ void Process::eoi_()
if (active())
{
close();
d_data->d_exitStatus = waitForChild();
d_exitStatus = waitForChild();
}
}
#include "process.ih"
int Process::exitStatus() const
{
return d_data->d_exitStatus;
}
inline int Process::exitStatus() const
{
return d_exitStatus;
}
......@@ -7,9 +7,9 @@ void Process::limiter(Process *process)
if (timeLimit == 0) // no timelimit: thread immediately
return; // ends
unique_lock<mutex> lock(process->d_data->d_mutex); // get the lock
unique_lock<mutex> lock(process->d_mutex); // get the lock
volatile ChildAction &action = process->d_data->d_action;
volatile ChildAction &action = process->d_action;
action = TIME_LIMIT;
......@@ -22,7 +22,7 @@ void Process::limiter(Process *process)
// When the time limit is reached
// the loop breaks, and d_action is
// TIME_LIMIT.
if (process->d_data->d_condition.wait_for(
if (process->d_condition.wait_for(
lock, chrono::seconds(timeLimit)) == cv_status::timeout)
break;
}
......
......@@ -3,7 +3,7 @@
Process &Process::operator()(IOMode mode, ProcessType type, size_t timeLimit,
size_t bufSize)
{
d_data->d_bufSize = bufSize;
d_bufSize = bufSize;
d_timeLimit = timeLimit;
d_processType = type;
sanitizeIOMode(mode);
......
#include "process.ih"
Process &Process::operator<<(std::ostream &(*pf)(std::ostream &))
{
if (active())
static_cast<std::ostream &>(*this) << pf;
return *this;
}
......@@ -4,6 +4,9 @@
#include <string>
#include <ostream>
#include <istream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <bobcat/fork>
#include <bobcat/string>
......@@ -13,6 +16,7 @@
#include <bobcat/ofdbuf>
#include <bobcat/iostream>
#include <bobcat/processenums>
#include <bobcat/signal>
#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
#ifndef BOBCAT_DIY_CLOEXEC_
......@@ -23,9 +27,8 @@
namespace FBB
{
struct ProcessData;
struct Process: private Fork, public IOStream, public ProcessEnums
struct Process: private Fork, private SignalHandler,
public IOStream, public ProcessEnums
{
friend Process &operator|(Process &lhs, Process &rhs);
......@@ -74,8 +77,14 @@ struct Process: private Fork, public IOStream, public ProcessEnums
RetPid d_child;
ProcessData *d_data;
char d_notUsed[sizeof(RetPid) - sizeof(ProcessData *)];
std::thread d_limit;
volatile ChildAction d_action = CHILD_ENDED;
std::mutex d_mutex;
std::condition_variable d_condition;
size_t d_bufSize;
int d_exitStatus;
#ifdef BOBCAT_DIY_CLOEXEC_
int d_closedByChild = 0; // DIY CLOSE_ON_EXEC
......@@ -101,13 +110,13 @@ struct Process: private Fork, public IOStream, public ProcessEnums
Process &operator=(Process const &other) = delete;
size_t bufSize() const; // returns current buffer size
size_t bufSize() const; // returns current buffer size .f
IOMode ioMode() const; // returns default IOMode .f
ProcessType processType() const; // returns default ProcessType .f
size_t timeLimit() const; // returns default time limit .f
void setBufSize(size_t bufSize);
void setIOMode(IOMode mode); // change IOMode .f
void setBufSize(size_t bufSize); // .f
void setIOMode(IOMode mode); // change IOMode .f
void setProcessType(ProcessType type); // .f
......@@ -147,13 +156,14 @@ struct Process: private Fork, public IOStream, public ProcessEnums
template <typename Type>
Process &operator>>(Type &value); // opextract.f
Process &operator<<(std::ostream &(*pf)(std::ostream &));
int stop(); // terminate a running childprocess
void close(); // closes input to the child
int eoi(); // closes input and waits for
// the child to end
using Fork::waitForChild;
int exitStatus() const;
int exitStatus() const; // .f
bool active();
......@@ -185,6 +195,8 @@ struct Process: private Fork, public IOStream, public ProcessEnums
void parentProcess() override;
void parentRedirections() override;
void signalHandler(size_t signum) override;
void eoi_() override;
void newPipe(Pipe &pipe);
......@@ -209,7 +221,9 @@ struct Process: private Fork, public IOStream, public ProcessEnums
static void limiter(Process *process);
};
#include "bufsize.f"
#include "childoutstream.f"
#include "exitstatus.f"
#include "iomode.f"
#include "opaddis.f"
#include "opextract.f"
......@@ -217,6 +231,7 @@ struct Process: private Fork, public IOStream, public ProcessEnums
#include "opfun2.f"
#include "opinsert.f"
#include "processtype.f"
#include "setbufsize.f"
#include "setcommand.f"
#include "setiomode.f"
#include "setprocesstype.f"
......
......@@ -5,7 +5,6 @@
#include <fcntl.h>
#include <algorithm>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
......@@ -14,8 +13,6 @@
#include "../redirector/redirector"
#include "../exception/exception"
#include "../processdata/processdata.decl"
using namespace std;
using namespace FBB;
......
......@@ -16,8 +16,10 @@ Process::Process(IOMode mode, ProcessType processType,
d_iChildOut(0),
d_iChildErr(0),
d_data(new ProcessData(bufSize))
d_bufSize(bufSize == 0 ? 1 : bufSize)
{
Signal::instance().add(SIGCHLD, *this);
d_setMode = sanitizeIOMode(mode);
// connect the input and output streams to Process
......
#include "process.ih"
void Process::setBufSize(size_t bufSize)
{
d_data->d_bufSize = bufSize == 0 ? 1 : bufSize;
}
inline void Process::setBufSize(size_t bufSize)
{
d_bufSize = bufSize == 0 ? 1 : bufSize;
}
#include "processdata.ih"
#include "process.ih"
void ProcessData::signalHandler(size_t signal)
void Process::signalHandler(size_t signal)
{
if (d_action == TIME_LIMIT)
{
......
......@@ -18,7 +18,7 @@ void Process::start(IOMode mode, ProcessType type, size_t timeLimit,
sanitizeIOMode(mode);
// not yet using the time limit
// thread
d_data->d_limit = thread(limiter, this);
d_limit = thread(limiter, this);
forking();
setBufSize(savedBufSize);
......
......@@ -17,7 +17,7 @@ int Process::stop()
discontinue(d_child);
d_data->d_limit.join();
d_limit.join();
d_active = false;
......
#include "processdata.ih"
ProcessData::~ProcessData()
{
Signal::instance().remove(SIGCHLD, *this);
}
#include "processdata.ih"
ProcessData::
{
}
#define LIBRARY "processdata"
#define AUXFLAGS "-pthread"
#include "../icmconf"
#ifndef INCLUDED_PROCESSDATA_DECL_
#define INCLUDED_PROCESSDATA_DECL_
#include <thread>
#include <mutex>
#include <condition_variable>
#include "../signal/signal"
#include "../processenums/processenums"
namespace FBB
{
struct ProcessData: private ProcessEnums, public SignalHandler
{
std::thread d_limit;
volatile ChildAction d_action = CHILD_ENDED;
std::mutex d_mutex;
std::condition_variable d_condition;
size_t d_bufSize;
int d_exitStatus;
ProcessData(size_t bufSize);
~ProcessData() override;
private:
void signalHandler(size_t signum) override;
};
} // FBB
#endif
#include "processdata.decl"
//#include <iostream> // TMP
//#include <chrono>
//#include <fcntl.h>
//#include <unistd.h>
//
//#include <sys/types.h>
//#include <sys/wait.h>
//
//#include "../exception/exception"
//#include "../redirector/redirector"
using namespace std;
using namespace FBB;
// #include "retpid1.f"
#include "processdata.ih"
ProcessData::ProcessData(size_t bufSize)
:
d_bufSize(bufSize == 0 ? 1 : bufSize)
{
Signal::instance().add(SIGCHLD, *this);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment