Move the semaphore to its own class and add some tests for it