Browse Source

merging

sync
Volker Birk 7 years ago
parent
commit
f3e9fc2861
  1. 5
      Makefile
  2. 9
      pc_container.hh
  3. 117
      test_library.cc

5
Makefile

@ -27,7 +27,7 @@ clean:
distclean: clean
rm -Rf .gnupg .pEp_management*
test: test_adapter
test: test_adapter test_library
ifeq ($(HOME),$(PREFIX))
-ln -fs $$HOME/lib
endif
@ -36,6 +36,9 @@ endif
test_adapter: test_adapter.o $(TARGET)
$(CXX) -o $@ -L$(PEP)/lib -lpEpEngine -L. -lpEpAdapter $<
test_library: test_library.o $(TARGET)
$(CXX) -o $@ -L$(PEP)/lib -lpEpEngine -L. -lpEpAdapter $<
install: $(TARGET)
-mkdir -p $(PEP)/include
cp $(HEADERS) $(PEP)/include

9
pc_container.hh

@ -10,6 +10,9 @@
namespace pEp
{
enum class PC_State { Illegal = 0, Created = 1, Deleted = 2, Changed = 3 };
// Producer/Consumer container.
//
// The "Producer" works on a std::list: inserts, changes, erases elements and
@ -27,6 +30,8 @@ public:
{
Pdata* pdata; // data of the producer. Will be nullptr for erased elements
Cdata* cdata; // data of the consumer.
PC_State state() const noexcept { return PC_State((pdata!=nullptr) + (cdata!=nullptr)*2); }
};
typedef std::list<PC> Container;
@ -91,7 +96,7 @@ public:
// does the element still exists?
if( pc.pdata &&
std::find_if( c.cbegin(), c.cend(), [&pc](PC& element) { return pc.pdata == element.pdata; } ) == c.cend()
std::find_if( c.cbegin(), c.cend(), [&pc](const PC& element) { return pc.pdata == element.pdata; } ) == c.cend()
)
{
// No, not anymore. So mark it as erased element for the consumer:
@ -102,7 +107,7 @@ public:
}
private:
typename Container c;
Container c;
::utility::locked_queue< PC > changed;
};

117
test_library.cc

@ -0,0 +1,117 @@
// small unittest program for libpEpAdapter
// TODO: use Gtest or the like for more modular unit tests!
#include "pc_container.hh"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <thread>
using namespace pEp;
// Producer's data:
class P
{
public:
P(int i)
: data{new char[64]}
{
snprintf(data, 63, "%i", i);
}
P(const P&) = delete;
void operator=(const P&) = delete;
~P()
{
std::cerr << "~P(): data=" << (data ? data : "(NULL)" ) << '\n';
delete[] data;
}
char* data;
};
// Consumer's data:
class C
{
public:
C(int _i) : i(_i) {}
int i;
};
pc_container<P,C> pc;
void consumer_thread()
{
bool keep_running = true;
int sum = 0;
while(keep_running)
{
auto q = pc.get_changed(); // might block, that is okay.
switch(q.state())
{
case PC_State::Created:
{
const int value = atoi( q.pdata->data );
if(value<0)
{
std::cerr << "Q\n";
keep_running = false;
}else{
std::cerr << "C";
q.cdata = new C( value );
sum += q.cdata->i;
}
break;
}
case PC_State::Deleted:
{
std::cerr << "D";
sum -= q.cdata->i;
delete q.cdata;
break;
}
case PC_State::Changed:
{
std::cerr << "X";
sum -= q.cdata->i;
delete q.cdata;
q.cdata = new C( atoi( q.pdata->data ) );
sum += q.cdata->i;
break;
}
default: throw "Illegal state";
}
}
std::cout << "Consumer sum: " << sum << ".\n";
}
int main()
{
for(int i=0; i<10; ++i)
{
pc.insert( new P(i) );
}
std::thread t{ &consumer_thread };
for(int i=10; i<100; ++i)
{
pc.insert( new P(i) );
}
while( !pc.empty() )
{
auto q = pc.begin();
delete q->pdata;
pc.erase( q );
}
pc.insert( new P(-1) );
t.join();
}
Loading…
Cancel
Save