Skip to content

Commit

Permalink
Merge pull request #2 from martelkr/1-initial-implementation
Browse files Browse the repository at this point in the history
1 initial implementation
  • Loading branch information
martelkr committed Aug 16, 2023
2 parents 2c7f6f2 + 8684d5f commit a3d94be
Show file tree
Hide file tree
Showing 12 changed files with 406 additions and 1 deletion.
33 changes: 33 additions & 0 deletions .github/workflows/clang.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: clang

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
Clang:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install gtest manually
run: sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a

- name: Build and Test
run: |
cmake . -B ${{github.workspace}}/build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
cmake --build ${{github.workspace}}/build
ctest -VV --test-dir ${{github.workspace}}/build
- name: Generate a code coverage report
uses: threeal/gcovr-action@latest
with:
gcov-executable: llvm-cov gcov

43 changes: 43 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: cmake

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
Linux:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install gtest
run: sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a

- name: Build and test
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
ctest -VV --test-dir ${{github.workspace}}/build -C ${{env.BUILD_TYPE}}
Windows:
runs-on: windows-latest

steps:
- uses: actions/checkout@v3

- name: Install gtest
uses: MarkusJx/googletest-installer@v1.1.1

- name: Build and Test
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
ctest -VV --test-dir ${{github.workspace}}/build -C ${{env.BUILD_TYPE}}
35 changes: 35 additions & 0 deletions .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: cppcheck

on:
push:
branches: [ "main" ]
# this currently does not work on pull requests
# https://github.com/deep5050/cppcheck-action/issues/48
#pull_request:
# branches: [ "main" ]

env:
BUILD_TYPE: Release

jobs:
Linux-cppcheck:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: cppcheck
uses: deep5050/cppcheck-action@main
with:
github_token: ${{ secrets.GITHUB_TOKEN}}
enable: all
force_language: c++
std: c++20
platform: unix64
other_options: --bug-hunting -I inc

- name: publish report
uses: mikeal/publish-to-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_NAME: 'main'
36 changes: 36 additions & 0 deletions .github/workflows/profile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: coverage

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
BUILD_TYPE: Debug

jobs:
Coverage:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install gtest
run: sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a

- name: Coverage configure
run: cmake -DCMAKE_BUILD_TYPE=Coverage .

- name: Coverage build
run: cmake --build . --config Coverage

- name: Coverage test
run: ctest -VV -C Coverage

- name: Generate Test Report
uses: threeal/gcovr-action@latest
with:
coveralls-send: true
github-token: ${{ secrets.GITHUB_TOKEN }}

49 changes: 49 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

testcppsocket
.vscode
CMakeCache.txt
CMakeFiles
cmake_install.cmake
Makefile
.vs
*.vcxproj*
*.sln
test/Debug
test/Release
x64
bin
test/testcppsocket.dir
CTestTestfile.cmake
Testing
25 changes: 25 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
cmake_minimum_required (VERSION 3.22.1)

set(CMAKE_CXX_STANDARD 20)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin)

FILE(READ "VERSION" project_version)
STRING(STRIP "${project_version}" project_version)

SET(LICENSE "MIT")

project(cppsocket VERSION ${project_version} LANGUAGES CXX)

if (CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-DLINUX)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_definitions(-DLINUX)
else()
add_definitions(-DWINDOWS)
endif()

include_directories(inc)

enable_testing()
add_subdirectory(test)
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 martelkr
Copyright (c) 2023 Kevin Martel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# C++ client/server with SSL/TLS support (header file only)
[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)
![cmake Build](https://github.com/martelkr/cppPeriodicThread/actions/workflows/cmake.yml/badge.svg)
![clang Build](https://github.com/martelkr/cppPeriodicThread/actions/workflows/clang.yml/badge.svg)
![profile Build](https://github.com/martelkr/cppPeriodicThread/actions/workflows/profile.yml/badge.svg)
![cppcheck Build](https://github.com/martelkr/cppPeriodicThread/actions/workflows/cppcheck.yml/badge.svg)
[![Coverage Status](https://coveralls.io/repos/github/martelkr/cppPeriodicThread/badge.svg?branch=main)](https://coveralls.io/github/martelkr/cppPeriodicThread?branch=main)
![cpp-linter](https://github.com/martelkr/cppPeriodicThread/actions/workflows/linter.yml/badge.svg)

## About
This is a header file only implementation of a C++20 periodic jthread.

Compilation has been tested with:
- GCC 11.3.0 (GNU/Linux Ubuntu 22.04.1 LTS)
- cmake 3.22.1
- googletest 1.11.0-3
- clang 14.0.0-1ubuntu1
- Visual Studio Community 2022 17.4.4 (64-bit) (Windows 11)
- cmake 3.26.0-rc1
- googletest 1.13.0

## Usage

### Periodic Thread

Create a CPeriodicThread object for executing a function periodically.

```cpp
// assuming "myPeriodicThread" is a valid void return function to call periodically
std::function<void()> f = myPeriodicThread;
// call "f" every 1000 millliseconds or 1 second
CPeriodicThread p(f, 1000);
```
The periodicity of the called function doesn not subtract out for the execution of the
user provided function. For example, if a periodicity of 1 second is requested and the
called user function takes 0.5 seconds to execute, the function will be called the
second time at start time + 1.5 seconds and second function call will be called at
start time + 3 seconds and so forth.
## Thread Safety
Each periodic thread is its own instance and thread safe by itself.
## Installation
Use the `CPeriodicThread.hpp` file in your source tree and include it in the file that need to use it.
## Run Unit Tests
Unit tests run with ctest:
```
ctest -C debug
```
## Contribute
All contributions are highly appreciated.
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1
47 changes: 47 additions & 0 deletions inc/CPeriodicThread.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

/**
* @brief Create a C++20 periodic jthread
*
*/
class CPeriodicThread
{
public:

/**
* @brief Construct a new CPeriodicThread object
*
* @param func Function to call periodically
* @param periodicityMilliseconds The millisecond period at which to call the provided function
*/
CPeriodicThread(std::function<void()>& func, const unsigned int periodicityMilliseconds)
: m_thread([periodicityMilliseconds, func](std::stop_token stopToken)
{
const std::chrono::milliseconds period(periodicityMilliseconds);
while(!stopToken.stop_requested())
{
func();
std::this_thread::sleep_for(period);
}
})
{
}

/**
* @brief Destroy the CPeriodicThread object
*
*/
~CPeriodicThread(void)
{
m_thread.request_stop();
}

private:

/// @brief The jthread to contain the periodic function call
std::jthread m_thread;
};
43 changes: 43 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
set(CMAKE_CXX_FLAGS "-g -O0 -Wall -Werror --coverage")
set(CMAKE_C_FLAGS "-g -O0 -Wall -Werror --coverage")
else()
set(CMAKE_CXX_FLAGS "-O3 -Wall -Werror")
endif()
find_package(GTest REQUIRED)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
set(CMAKE_CXX_FLAGS "-Wall /O2")
if(DEFINED ENV{CI})
# github action CI needs
set(GTEST_LIBRARY "D:/gtest/lib/gtest.lib")
set(GTEST_INCLUDE_DIR "D:/gtest/include")
set(GTEST_MAIN_LIBRARY "D:/gtest/lib/gtest_main.lib")
else()
# this may not be needed or need changing but I needed it
# this requires setting Windows environment settings for this user with these correct values
set(GTEST_LIBRARY $ENV{GTEST_LIBRARY})
set(GTEST_INCLUDE_DIR $ENV{GTEST_INCLUDE_DIR})
set(GTEST_MAIN_LIBRARY $ENV{GTEST_LIBRARY})
endif()
find_package(GTest REQUIRED)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "-O3 -Wall -Werror")
find_package(GTest REQUIRED)
else()
message(FATAL_ERROR "Failed to find correct compiler")
endif()

include_directories(../inc)

add_executable(testperiodic TestPeriodicThread.cpp)

target_include_directories(testperiodic PRIVATE ${GTEST_INCLUDE_DIR})

target_link_libraries(testperiodic ${GTEST_LIBRARIES})

add_test(
NAME gtestperiodicthread
COMMAND testperiodic
)
Loading

0 comments on commit a3d94be

Please sign in to comment.