3

I have a following set of codes specific to Windows,

    //1: Declaring HANDLE
    HANDLE *m_handle;
    
   //2: Creating HANDLE instance   
   int m_Count = 4;
   m_handle = new HANDLE[m_Count];

   //3: Creating Events
   for (int i = 0; i < m_Count ; i++)
    {
        m_handle [i] = CreateEvent(NULL, FALSE, FALSE, NULL);
    }

   //4: Synchronous API
   DWORD dwEvent = WaitForMultipleObjects(m_Count, m_handle, TRUE, 30000);

   //5: Closing the HANDLE
   for (int i = 0; i < m_Count; i++)
    {
        CloseHandle(m_handle[i]);
    }

How to write the same set of code in case of Linux?

Sharath Kumar
  • 73
  • 1
  • 9
  • 2
    What is it that you are trying to do, exactly? – Asteroids With Wings Jul 16 '20 at 12:10
  • you're using C++, this looks like win32 specific version of using a collection of `std::condition_variable`s. So just use those if all you want to do is to wait for signals from other threads – PeterT Jul 16 '20 at 12:11
  • 1
    There's nothing identical to Windows event objects in Linux. There are several similar facilities, conceptually, like basic condition variables, event file descriptors, and named pipes, with various abilities in terms of waiting until one or multiple objects get triggered. In general, you can't take something that uses MS-Windows APIs and rewrite them, line by line, into Linux equivalents. The two operating systems are fundamentally different. – Sam Varshavchik Jul 16 '20 at 12:13
  • If you want some cross-platform event-based APIs, look into Qt. But as it stands, your question is to vague to be answered. – Dan M. Jul 16 '20 at 12:28
  • Hi. Thanks for the response. I'm basically performing multi-threading operation. Here, number of Events I created is equivalent to number of thread instance. I am trying to call a various methods under thread which takes event handles as an argument. These methods will perform specified operation and Set the Event indicating the operation is completed. Further I will be checking if the process is completed in given duration. Finally I will be destroying the Handle inside the destructor. I need to perform the same operations for Linux. – Sharath Kumar Jul 16 '20 at 12:31
  • There's no such thing as "event handles" under Linux. So, your first step will be to divorce yourself from this concept entirely, and instead focus on the functionality they provide. The next thing for you to do would be to research condition variables (which is a part of C++ core library, and not Linux-specific), and Linux-specific event file descriptors, and the `epoll()` system call, and how they work, and determine whether that will work for you. – Sam Varshavchik Jul 16 '20 at 13:00
  • Your approach is probably wrong. **Don't try to mimic Windows on Linux or vice-versa.** Read [*Advanced Linux Programming*](https://mentorembedded.github.io/advancedlinuxprogramming/) then [syscalls(2)](https://man7.org/linux/man-pages/man2/syscalls.2.html) with a [Pthread tutorial](https://computing.llnl.gov/tutorials/pthreads/). Or use a cross-platform framework (like [Qt](http://qt.io/)...) – Basile Starynkevitch Jul 16 '20 at 13:33

1 Answers1

7

The replacement for CreateEvent is eventfd, you probably want EFD_CLOEXEC and EFD_NONBLOCK flags. Don’t use the semaphore flag unless you know what you’re doing.

The replacement for WaitForMultipleObjects is poll, specify the POLLIN flag in the requested events. Just keep in mind the event is not being reset by poll, it will stay signalled. Read 8 bytes from the eventfd handle to reset. The functionality is identical to manual-reset events on Windows.

To signal an event, call write on the eventfd handle, passing the address of a local uint64_t variable with value 1.

To destroy events once you no longer need them, just call close.

Update: I’ve just noticed you’re passing bWaitAll=TRUE to WaitForMultipleObjects.

Unfortunately, Linux poll can’t quite do that. It returns when timeout is expired, or when at least 1 handle becomes signaled, whichever happens first.

Still, the workaround is not too hard. You can emulate bWaitAll by calling poll multiple times in a loop until all of the events are signaled. No need to rebuild the array of handles, you can set file handle to a negative value for the events which became signaled after poll returned. Note that multiple of them may become signaled at once, poll return value tells how many of them did. Also don't forget to decrease the timeout value.

Soonts
  • 20,079
  • 9
  • 57
  • 130