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 ...@@ -68,7 +68,6 @@ osharedstream
pattern pattern
pipe pipe
process process
processdata
processenums processenums
ptriter ptriter
qpbufbase qpbufbase
......
...@@ -152,7 +152,13 @@ bobcat (5.00.00) ...@@ -152,7 +152,13 @@ bobcat (5.00.00)
* OMutexStream: * OMutexStream:
new class offering mutex protected ostream operations. new class offering mutex protected ostream operations.
* ProcessData:
Internal class previously used by Process to store the Pimpl-data. Now
discontinued.
* Process: * 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 - The mode parameter defined for the second through fourth constructor
must be a Process::IOMode value. The same applies to the function must be a Process::IOMode value. The same applies to the function
call operator previously accespting a size_t argument. call operator previously accespting a size_t argument.
...@@ -185,6 +191,7 @@ bobcat (5.00.00) ...@@ -185,6 +191,7 @@ bobcat (5.00.00)
* Fixed flaw in Log's FBB::fnl handling * 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) bobcat (4.09.00)
......
...@@ -16,54 +16,85 @@ manpagesection(MANIPULATORS) ...@@ -16,54 +16,85 @@ manpagesection(MANIPULATORS)
itb(FBB::center) defined in tt(bobcat/align) itb(FBB::center) defined in tt(bobcat/align)
This manipulator can be specified when constructing an bf(FBB::Align) This manipulator can be specified when constructing an bf(FBB::Align)
object to indicate that a table column should center its contents. object to indicate that a table column should center its contents.
itb(FBB::decindent) defined in tt(bobcat/indent) itb(FBB::decindent) defined in tt(bobcat/indent)
This manipulator reduces the indentation level. This manipulator reduces the indentation level.
itb(FBB::def) itb(FBB::def)
defined in tt(bobcat/table) defined in tt(bobcat/table)
This manipulator `completes' a bf(Table) object to a full rectangular This manipulator `completes' a bf(Table) object to a full rectangular
object. It can be inserted into a bf(Table) object. 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) itb(FBB::err) defined in tt(bobcat/msg)
Generates an error message. 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) 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) itb(FBB::fs) defined in tt(bobcat/tablebuf)
Starts the definition of the next element in a table. Starts the definition of the next element in a table.
itb(FBB::info) defined in tt(bobcat/msg) itb(FBB::info) defined in tt(bobcat/msg)
Generates an informational message. Generates an informational message.
itb(FBB::incindent) defined in tt(bobcat/indent) itb(FBB::incindent) defined in tt(bobcat/indent)
This manipulator will increment the indentation level. This manipulator will increment the indentation level.
itb(FBB::indent) defined in tt(bobcat/indent) itb(FBB::indent) defined in tt(bobcat/indent)
This manipulator inserts the currently defined number of indentation This manipulator inserts the currently defined number of indentation
blanks into an tt(ostream). blanks into an tt(ostream).
itb(FBB::indentdec) defined in tt(bobcat/indent) itb(FBB::indentdec) defined in tt(bobcat/indent)
This manipulator will insert, then reduce the indentation level. This manipulator will insert, then reduce the indentation level.
itb(FBB::indentinc) defined in tt(bobcat/indent) itb(FBB::indentinc) defined in tt(bobcat/indent)
This manipulator will insert, then increment the indentation level. This manipulator will insert, then increment the indentation level.
itb(FBB::lm) defined in tt(bobcat/ofoldbuf) itb(FBB::lm) defined in tt(bobcat/ofoldbuf)
This manipulator sets the left margin of bf(FBB::OFoldStream) objects. This manipulator sets the left margin of bf(FBB::OFoldStream) objects.
itb(FBB::mlm) defined in tt(bobcat/ofoldbuf) itb(FBB::mlm) defined in tt(bobcat/ofoldbuf)
This manipulator modifies (alters) the left margin of This manipulator modifies (alters) the left margin of
bf(FBB::OFoldStream) objects. bf(FBB::OFoldStream) objects.
itb(FBB::nlindent) defined in tt(bobcat/indent) itb(FBB::nlindent) defined in tt(bobcat/indent)
This manipulator will insert a newline, then indent. This manipulator will insert a newline, then indent.
itb(FBB::rs) defined in tt(bobcat/tablebuf) itb(FBB::rs) defined in tt(bobcat/tablebuf)
Starts the definition of the next row in a table. Starts the definition of the next row in a table.
itb(FBB::spool) defined in tt(bobcat/msg) itb(FBB::spool) defined in tt(bobcat/msg)
Generates a (partial) informational message. 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) itb(FBB::warning) defined in tt(bobcat/msg)
Generates a warning message. Generates a warning message.
) )
manpageseealso() manpageseealso()
bf(bobcat)(7), bf(columnwidth)(3bobcat), bf(equalwidth)(3bobcat), bf(bobcat)(7), bf(columnwidth)(3bobcat), bf(eoi)(3bobcat),
bf(indent)(3bobcat), bf(lm)(3bobcat), bf(equalwidth)(3bobcat), bf(indent)(3bobcat), bf(lm)(3bobcat),
bf(mlm)(3bobcat), bf(msg)(3bobcat), bf(table)(3bobcat) bf(mlm)(3bobcat), bf(msg)(3bobcat), bf(table)(3bobcat)
manpagebugs() manpagebugs()
None Reported. None Reported.
includefile(include/trailer) includefile(include/trailer)
...@@ -287,12 +287,13 @@ manpagesection(OVERLOADED OPERATORS) ...@@ -287,12 +287,13 @@ manpagesection(OVERLOADED OPERATORS)
itemization( itemization(
itb(Process &operator<<(Type value)) itb(Process &operator<<(Type value))
This operator inserts tt(value) into the child's standard This operator inserts tt(value) into the child's standard input
input stream. I.e., the child process reads tt(value) from its standard stream. I.e., the child process reads tt(value) from its standard input. A
input. A value of any type that can be inserted into an tt(ostream) can be value of any type that can be inserted into an tt(ostream) can be inserted
inserted into a tt(Process) object. Nothing happens if the member is used when into a tt(Process) object. Nothing happens if the member is used when the
the child process has terminated. The behavior of this operator is undefined child process has terminated. Manipulators like tt(std::endl) are also
unless tt(IOMode CIN) was specified. supported. The behavior of this operator is undefined unless tt(IOMode CIN)
was specified.
itb(Process &operator>>(Type value)) itb(Process &operator>>(Type value))
This operator extracts tt(value) from the child's standard output 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() ...@@ -4,6 +4,7 @@ Process::~Process()
{ {
stop(); stop();
delete d_data; // delete additional data // delete d_data; // delete additional data
Signal::instance().remove(SIGCHLD, *this);
} }
#include <iostream> #include <iostream>
#include "../../processenums/processenums" #include "../../processenums/processenums"
#include "../../processdata/processdata.decl"
#include "../process" #include "../process"
using namespace std; using namespace std;
...@@ -22,7 +21,7 @@ int main() ...@@ -22,7 +21,7 @@ int main()
if (not getline(cin, line)) if (not getline(cin, line))
return 0; return 0;
process << line << endl; // to /bin/cat process << line << endl; // to /bin/cat
line.clear(); line.clear();
if (not getline(process, line)) // from /bin/cat if (not getline(process, line)) // from /bin/cat
......
#include <iostream> #include <iostream>
#include "../../processenums/processenums" #include "../../processenums/processenums"
#include "../../processdata/processdata.decl"
#include "../process" #include "../process"
using namespace std; using namespace std;
...@@ -19,9 +18,3 @@ int main() ...@@ -19,9 +18,3 @@ int main()
p3 << cin.rdbuf() << eoi; p3 << cin.rdbuf() << eoi;
} }
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#include <iostream> #include <iostream>
#include "../../processenums/processenums" #include "../../processenums/processenums"
#include "../../processdata/processdata.decl"
#include "../process" #include "../process"
using namespace std; using namespace std;
......
...@@ -5,7 +5,7 @@ void Process::eoi_() ...@@ -5,7 +5,7 @@ void Process::eoi_()
if (active()) if (active())
{ {
close(); 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) ...@@ -7,9 +7,9 @@ void Process::limiter(Process *process)
if (timeLimit == 0) // no timelimit: thread immediately if (timeLimit == 0) // no timelimit: thread immediately
return; // ends 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; action = TIME_LIMIT;
...@@ -22,7 +22,7 @@ void Process::limiter(Process *process) ...@@ -22,7 +22,7 @@ void Process::limiter(Process *process)
// When the time limit is reached // When the time limit is reached
// the loop breaks, and d_action is // the loop breaks, and d_action is
// TIME_LIMIT. // TIME_LIMIT.
if (process->d_data->d_condition.wait_for( if (process->d_condition.wait_for(
lock, chrono::seconds(timeLimit)) == cv_status::timeout) lock, chrono::seconds(timeLimit)) == cv_status::timeout)
break; break;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Process &Process::operator()(IOMode mode, ProcessType type, size_t timeLimit, Process &Process::operator()(IOMode mode, ProcessType type, size_t timeLimit,
size_t bufSize) size_t bufSize)
{ {
d_data->d_bufSize = bufSize; d_bufSize = bufSize;
d_timeLimit = timeLimit; d_timeLimit = timeLimit;
d_processType = type; d_processType = type;
sanitizeIOMode(mode); 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 @@ ...@@ -4,6 +4,9 @@
#include <string> #include <string>
#include <ostream> #include <ostream>
#include <istream> #include <istream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <bobcat/fork> #include <bobcat/fork>
#include <bobcat/string> #include <bobcat/string>
...@@ -13,6 +16,7 @@ ...@@ -13,6 +16,7 @@
#include <bobcat/ofdbuf> #include <bobcat/ofdbuf>
#include <bobcat/iostream> #include <bobcat/iostream>
#include <bobcat/processenums> #include <bobcat/processenums>
#include <bobcat/signal>
#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) #if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
#ifndef BOBCAT_DIY_CLOEXEC_ #ifndef BOBCAT_DIY_CLOEXEC_
...@@ -23,9 +27,8 @@ ...@@ -23,9 +27,8 @@
namespace FBB namespace FBB
{ {
struct ProcessData; struct Process: private Fork, private SignalHandler,
public IOStream, public ProcessEnums
struct Process: private Fork, public IOStream, public ProcessEnums
{ {
friend Process &operator|(Process &lhs, Process &rhs); friend Process &operator|(Process &lhs, Process &rhs);
...@@ -74,8 +77,14 @@ struct Process: private Fork, public IOStream, public ProcessEnums ...@@ -74,8 +77,14 @@ struct Process: private Fork, public IOStream, public ProcessEnums
RetPid d_child; RetPid d_child;
ProcessData *d_data; std::thread d_limit;
char d_notUsed[sizeof(RetPid) - sizeof(ProcessData *)]; 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_ #ifdef BOBCAT_DIY_CLOEXEC_
int d_closedByChild = 0; // DIY CLOSE_ON_EXEC int d_closedByChild = 0; // DIY CLOSE_ON_EXEC
...@@ -101,13 +110,13 @@ struct Process: private Fork, public IOStream, public ProcessEnums ...@@ -101,13 +110,13 @@ struct Process: private Fork, public IOStream, public ProcessEnums
Process &operator=(Process const &other) = delete; 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 IOMode ioMode() const; // returns default IOMode .f
ProcessType processType() const; // returns default ProcessType .f ProcessType processType() const; // returns default ProcessType .f
size_t timeLimit() const; // returns default time limit .f size_t timeLimit() const; // returns default time limit .f
void setBufSize(size_t bufSize); void setBufSize(size_t bufSize); // .f
void setIOMode(IOMode mode); // change IOMode .f void setIOMode(IOMode mode); // change IOMode .f
void setProcessType(ProcessType type); // .f void setProcessType(ProcessType type); // .f
...@@ -147,13 +156,14 @@ struct Process: private Fork, public IOStream, public ProcessEnums ...@@ -147,13 +156,14 @@ struct Process: private Fork, public IOStream, public ProcessEnums
template <typename Type> template <typename Type>
Process &operator>>(Type &value); // opextract.f Process &operator>>(Type &value); // opextract.f
Process &operator<<(std::ostream &(*pf)(std::ostream &));
int stop(); // terminate a running childprocess int stop(); // terminate a running childprocess
void close(); // closes input to the child void close(); // closes input to the child
int eoi(); // closes input and waits for int eoi(); // closes input and waits for
// the child to end // the child to end
using Fork::waitForChild; using Fork::waitForChild;
int exitStatus() const; int exitStatus() const; // .f
bool active(); bool active();
...@@ -185,6 +195,8 @@ struct Process: private Fork, public IOStream, public ProcessEnums ...@@ -185,6 +195,8 @@ struct Process: private Fork, public IOStream, public ProcessEnums
void parentProcess() override; void parentProcess() override;
void parentRedirections() override; void parentRedirections() override;
void signalHandler(size_t signum) override;
void eoi_() override; void eoi_() override;
void newPipe(Pipe &pipe); void newPipe(Pipe &pipe);
...@@ -209,7 +221,9 @@ struct Process: private Fork, public IOStream, public ProcessEnums ...@@ -209,7 +221,9 @@ struct Process: private Fork, public IOStream, public ProcessEnums
static void limiter(Process *process); static void limiter(Process *process);
}; };
#include "bufsize.f"
#include "childoutstream.f" #include "childoutstream.f"
#include "exitstatus.f"
#include "iomode.f" #include "iomode.f"
#include "opaddis.f" #include "opaddis.f"
#include "opextract.f" #include "opextract.f"
...@@ -217,6 +231,7 @@ struct Process: private Fork, public IOStream, public ProcessEnums ...@@ -217,6 +231,7 @@ struct Process: private Fork, public IOStream, public ProcessEnums
#include "opfun2.f" #include "opfun2.f"
#include "opinsert.f" #include "opinsert.f"
#include "processtype.f" #include "processtype.f"
#include "setbufsize.f"
#include "setcommand.f" #include "setcommand.f"
#include "setiomode.f" #include "setiomode.f"
#include "setprocesstype.f" #include "setprocesstype.f"
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <algorithm> #include <algorithm>
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -14,8 +13,6 @@ ...@@ -14,8 +13,6 @@
#include "../redirector/redirector" #include "../redirector/redirector"
#include "../exception/exception" #include "../exception/exception"
#include "../processdata/processdata.decl"
using namespace std; using namespace std;
using namespace FBB; using namespace FBB;
......
...@@ -16,8 +16,10 @@ Process::Process(IOMode mode, ProcessType processType, ...@@ -16,8 +16,10 @@ Process::Process(IOMode mode, ProcessType processType,
d_iChildOut(0), d_iChildOut(0),
d_iChildErr(0), d_iChildErr(0),
d_data(new ProcessData(bufSize)) d_bufSize(bufSize == 0 ? 1 : bufSize)
{ {
Signal::instance().add(SIGCHLD, *this);
d_setMode = sanitizeIOMode(mode); d_setMode = sanitizeIOMode(mode);
// connect the input and output streams to Process // 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) if (d_action == TIME_LIMIT)
{ {
......
...@@ -18,7 +18,7 @@ void Process::start(IOMode mode, ProcessType type, size_t timeLimit, ...@@ -18,7 +18,7 @@ void Process::start(IOMode mode, ProcessType type, size_t timeLimit,
sanitizeIOMode(mode); sanitizeIOMode(mode);
// not yet using the time limit // not yet using the time limit
// thread // thread
d_data->d_limit = thread(limiter, this); d_limit = thread(limiter, this);
forking(); forking();
setBufSize(savedBufSize); setBufSize(savedBufSize);
......
...@@ -17,7 +17,7 @@ int Process::stop() ...@@ -17,7 +17,7 @@ int Process::stop()
discontinue(d_child); discontinue(d_child);
d_data->d_limit.join(); d_limit.join();
d_active = false; 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