Click here to Skip to main content
15,877,675 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to code a time out "function" that can work in a nested switch and case statement.
However my problem is the following, the first switch/case works like expected, on the other hand, the second switch doesn't work in any way.

My code:
C++
#include <windows.h>
#include <iomanip>
#include <iostream>
#include <string>

namespace jsw {
    namespace threading {
        class auto_event {
        public:
            auto_event() : _event(CreateEvent(0, false, false, 0)) {}

            BOOL wait(DWORD timeout = 1) const
            {
                return WaitForSingleObject(_event, timeout) == WAIT_OBJECT_0;
            }

            BOOL set() { return SetEvent(_event); }
            BOOL reset_event() { return ResetEvent(_event); }
        private:
            HANDLE _event;
        };

        class thread {
        public:
            static thread start(
                LPTHREAD_START_ROUTINE fn, LPVOID args = 0,
                DWORD state = 0, DWORD timeout = 20000)
            {
                return thread(CreateThread(0, 0, fn, args, state, 0), timeout);
            }

            static void sleep(DWORD milliseconds) { Sleep(milliseconds); }
            static void exit(DWORD exitCode) { ExitThread(exitCode); }
        public:
            thread(HANDLE thread, DWORD timeout) : _thread(thread), _timeout(timeout) {}
            ~thread() { CloseHandle(_thread); }

            DWORD exit_code() const
            {
                DWORD exitCode = NO_ERROR;

                GetExitCodeThread(_thread, &exitCode);

                return exitCode;
            }

            HANDLE handle() const { return _thread; }
            BOOL is_alive() const { return exit_code() == STILL_ACTIVE; }
            DWORD join() { return WaitForSingleObject(_thread, _timeout); }
            DWORD suspend() { return SuspendThread(_thread); }
            DWORD resume() { return ResumeThread(_thread); }
            BOOL abort(DWORD exitCode) { return THREAD_TERMINATE; }
        private:
            HANDLE _thread;
            DWORD _timeout;
        };
    }
}

DWORD WINAPI get_option(LPVOID args)
{
    using namespace jsw::threading;

    int* option = (int*)((LPVOID*)args)[0];
    auto_event* e = (auto_event*)((LPVOID*)args)[1];

    std::cout << "Option: ";
    std::cin >> std::setw(1) >> *option;

    std::cin.clear();
    std::cin.ignore(INT_MAX, '\n');
    e->set();

    return NO_ERROR;
}

int main()
{
    using namespace jsw::threading;

    int option{};
    bool run{ true };
    auto_event e;
    LPVOID args[2] = { &option, &e };

    while (run)
    {
        thread worker = thread::start(get_option, args);

        if (e.wait(10000)) {
            system("cls");
            std::cout << option << std::endl;
            switch (option) {
            case 1:
                do {
                    std::cout << "Option: ";
                    std::cin >> option;
                    switch (option) {
                    case 1: std::cout << "Option 1 inside switch" << std::endl;
                        break;
                    case 2: std::cout << "Option 2 inside switch" << std::endl;
                        break;
                    case 3: std::cout << "Option 3 inside switch" << std::endl;
                        break;
                    case 4: 
                        break;
                    default: std::cout << "Option not valid!" << std::endl;
                        break;
                    }
                } while (option != 4);
                break;
            case 2:std::cout << "Option 2" << std::endl;
                break;
            case 3: run = false;
                break;
            default: std::cout << "Option not valid!" << std::endl;
                continue;
            }
        }
        else {
            worker.abort(NO_ERROR);
            system("cls");
            std::cout << "***PROGRAM END***\n";
            run = false;
        }
    }
}


What I have tried:

I tried multiple things; like directly using cin, which does make the switch/case partially work, however, since I'm not going through the WINAPI get_option function the timer doesn't work. If I try to use the do...while loop without cin then I get stuck in an infinite loop and if I get completely rid off the do...while loop (and cin) then I can't stay in the second switch/case, I always go back to the first one.

So if possible can somebody tell me how to fix this problem?
Posted
Updated 7-Apr-23 12:38pm
Comments
Richard MacCutchan 8-Apr-23 8:16am    
I have run your code a number of times with different options but I cannot figure out what it is supposed to be doing. I suggest you use the Improve question link above, and add a more detailed explanation of what is not working.
RexyCode 10-Apr-23 10:46am    
Sorry for being late on the answer, so to resume my problem in the shortest possible way; I'm trying to get the second switch statement to work like the first one, however, my "thread timer" can't seem to stay in the second switch statement, it always ends up going back to my first switch (which I don't want unless I explicitly use the exit option which is 4).
RexyCode 10-Apr-23 10:48am    
I describe in a bit more detail some of the problems I have in the section "What I have tried:" I hope it helps you understand my problem.
Thank you in advance!
Richard MacCutchan 10-Apr-23 11:49am    
As far as I can see you are using the same variable (option) for the inner and outer switch statement. This means that when the inner ends the value is not the one that was initially returned to the outer block. Change the code so they each use a different variable name.
RexyCode 14-Apr-23 10:11am    
I have tried to add different variable names, yet I didn't manage to find a way to make it work.
Plus, doing this would make the program a lot less efficient and harder to read which I'm trying to avoid.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900