Changeset 8:dba41f33ddce in xplcommon


Ignore:
Timestamp:
12/29/12 08:01:50 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Clarified the blocking and non-blocking behaviour and extended the test program to test both

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/xplcommon/WaitableEvent.h

    r7 r8  
    4444 * An event on which one can wait with a waiter.
    4545 */
    46 class WaitableEvent : public Waitable
     46class WaitableEvent : public Waitable, public Failable
    4747{
    4848public:
    4949    /**
    5050     * Construct the event.
     51     *
     52     * @param waiter the waiter to be used for waiting. If given, the
     53     * check() function will always return immediately. If not given,
     54     * the check() function may block and returns only when the event
     55     * is fired.
    5156     */
    5257    WaitableEvent(Waiter* waiter = 0);
  • src/xplcommon/posix/WaitableEvent.cc

    r6 r8  
    4848
    4949WaitableEvent::WaitableEvent(Waiter* waiter) :
    50     Waitable(waiter, eventfd(0, EFD_NONBLOCK), POLLIN)
     50    Waitable(waiter, eventfd(0, (waiter==0) ? 0 : EFD_NONBLOCK), POLLIN),
     51    fired(false)
    5152{
    5253    assert(fd>=0);
     
    6768    if (write(fd, &one, sizeof(one))<0) {
    6869        if (errno!=EAGAIN) {
    69             perror("xplcommon::posix::WaitableEvent::fire: write");
    70             assert(0);
     70            setErrorCode(errno);
    7171        }
    7272    }
     
    7777bool WaitableEvent::check()
    7878{
    79     if (fired) {
     79    if (doCheck()) {
    8080        fired = false;
    8181        return true;
     
    9797{
    9898    if ((events&POLLIN)==POLLIN) {
    99         uint64_t value = 0;
    100         if (read(fd, &value, sizeof(value))<0) {
    101             if (errno!=EAGAIN) {
    102                 perror("xplcommon::posix::WaitableEvent::handleEvents: read");
    103                 assert(0);
    104             }
    105         } else {
    106             fired = value>0;
     99        doCheck();
     100    }
     101}
     102
     103//------------------------------------------------------------------------------
     104
     105bool WaitableEvent::doCheck(bool fromHandleEvents)
     106{
     107    if (failed()) return false;
     108    if (!fromHandleEvents && fired) return true;
     109
     110    uint64_t value = 0;
     111    if (read(fd, &value, sizeof(value))<0) {
     112        if (errno!=EAGAIN) {
     113            setErrorCode(errno);
    107114        }
     115    } else {
     116        fired = fired || value>0;
    108117    }
     118
     119    return fired;
    109120}
    110121
  • src/xplcommon/posix/WaitableEvent.h

    r6 r8  
    3434#include "Waitable.h"
    3535
     36#include "../Failable.h"
     37
    3638//------------------------------------------------------------------------------
    3739
     
    4345 * An event on which one can wait with a waiter.
    4446 */
    45 class WaitableEvent : public Waitable
     47class WaitableEvent : public Waitable, public Failable
    4648{
    4749private:
     
    8385     */
    8486    virtual void handleEvents(short events);
     87
     88private:
     89    /**
     90     * Perform the real check. If we already know that we are fired,
     91     * just return true. Otherwise try to read from the event fd.
     92     */
     93    bool doCheck(bool fromHandleEvents = false);
    8594};
    8695
  • test/testevent.cc

    r4 r8  
    8989//------------------------------------------------------------------------------
    9090
     91class BlockingServerThread : public Thread
     92{
     93private:
     94    WaitableEvent event;
     95
     96public:
     97    WaitableEvent& getEvent();
     98
     99    virtual void run();
     100};
     101
     102//------------------------------------------------------------------------------
     103
     104inline WaitableEvent& BlockingServerThread::getEvent()
     105{
     106    return event;
     107}
     108
     109//------------------------------------------------------------------------------
     110
     111void BlockingServerThread::run()
     112{
     113    printf("BlockingServerThread::run: waiting...\n");
     114    if (event.check()) {
     115        printf("BlockingServerThread::run: waiting done\n");
     116    } else {
     117        printf("BlockingServerThread::run: waiting failed\n");
     118    }
     119    printf("BlockingServerThread::run: finished\n");
     120}
     121
     122
     123//------------------------------------------------------------------------------
     124//------------------------------------------------------------------------------
     125
    91126class ClientThread : public Thread
    92127{
     
    120155//------------------------------------------------------------------------------
    121156
    122 int main()
     157template <class Server> void runTest()
    123158{
    124     ServerThread serverThread;
     159    Server serverThread;
    125160    ClientThread clientThread(serverThread.getEvent());
    126161
     
    134169    serverThread.join();
    135170    printf("Both threads returned\n");
     171}
     172
     173//------------------------------------------------------------------------------
     174//------------------------------------------------------------------------------
     175
     176int main()
     177{
     178    printf("Running the event test with a non-blocking WaitableEvent\n\n");
     179    runTest<ServerThread>();
     180
     181    printf("\n\nRunning the event test with a blocking WaitableEvent\n\n");
     182    runTest<BlockingServerThread>();
    136183
    137184    return 0;
Note: See TracChangeset for help on using the changeset viewer.