Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
quasar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jens Nolte
quasar
Commits
b3a13dd9
Commit
b3a13dd9
authored
3 years ago
by
Jens Nolte
Browse files
Options
Downloads
Patches
Plain Diff
Implement timerfd
parent
a2be2ae2
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#2595
passed
3 years ago
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
quasar.cabal
+1
-0
1 addition, 0 deletions
quasar.cabal
src/Quasar/Timer/PosixTimer.hsc
+3
-0
3 additions, 0 deletions
src/Quasar/Timer/PosixTimer.hsc
src/Quasar/Timer/TimerFd.hs
+98
-0
98 additions, 0 deletions
src/Quasar/Timer/TimerFd.hs
with
102 additions
and
0 deletions
quasar.cabal
+
1
−
0
View file @
b3a13dd9
...
...
@@ -98,6 +98,7 @@ library
Quasar.Subscribable
Quasar.Timer
Quasar.Timer.PosixTimer
Quasar.Timer.TimerFd
Quasar.Utils.Exceptions
Quasar.Utils.ExtraT
hs-source-dirs:
...
...
This diff is collapsed.
Click to expand it.
src/Quasar/Timer/PosixTimer.hsc
+
3
−
0
View file @
b3a13dd9
...
...
@@ -2,9 +2,12 @@
module Quasar.Timer.PosixTimer (
ClockId(..),
toCClockId,
TimerSetTimeMode(..),
CTimeSpec(..),
defaultCTimeSpec,
CITimerSpec(..),
defaultCITimerSpec,
newPosixTimer,
newUnmanagedPosixTimer,
setPosixTimer,
...
...
This diff is collapsed.
Click to expand it.
src/Quasar/Timer/TimerFd.hs
0 → 100644
+
98
−
0
View file @
b3a13dd9
{-# LANGUAGE CApiFFI #-}
module
Quasar.Timer.TimerFd
(
TimerFd
,
newTimerFd
,
setTimer
,
setInterval
,
disarm
,
)
where
import
Control.Concurrent
import
Control.Monad.Catch
import
Foreign
import
Foreign.C
import
GHC.Conc
(
closeFdWith
)
import
GHC.IO.Handle.FD
import
Quasar.Awaitable
import
Quasar.Async
import
Quasar.Disposable
import
Quasar.Prelude
import
Quasar.ResourceManager
import
Quasar.Timer.PosixTimer
import
System.IO
import
System.Posix.Types
foreign
import
capi
"sys/timerfd.h timerfd_create"
c_timerfd_create
::
CClockId
->
CInt
->
IO
TimerFd
foreign
import
capi
"sys/timerfd.h timerfd_settime"
c_timerfd_settime
::
TimerFd
->
CInt
->
Ptr
CITimerSpec
->
Ptr
CITimerSpec
->
IO
CInt
foreign
import
capi
"unistd.h read"
c_timerfd_read
::
TimerFd
->
Ptr
Word64
->
CSize
->
IO
CInt
foreign
import
capi
"unistd.h close"
c_timerfd_close
::
TimerFd
->
IO
CInt
foreign
import
capi
"sys/timerfd.h value TFD_CLOEXEC"
c_TFD_CLOEXEC
::
CInt
newtype
TimerFd
=
TimerFd
Fd
deriving
stock
(
Eq
,
Show
)
deriving
newtype
Num
newTimerFd
::
MonadResourceManager
m
=>
ClockId
->
IO
()
->
m
TimerFd
newTimerFd
clockId
callback
=
mask_
do
timer
<-
liftIO
$
runInBoundThread
do
throwErrnoIfMinus1
"timerfd_create"
do
c_timerfd_create
(
toCClockId
clockId
)
c_TFD_CLOEXEC
workerTask
<-
async
$
liftIO
$
worker
timer
registerAsyncDisposeAction
do
await
$
isDisposed
workerTask
timerFdClose
timer
pure
timer
where
worker
::
TimerFd
->
IO
()
worker
timer
@
(
TimerFd
fd
)
=
forever
do
-- Block until timer is expired using the GHC runtime.
-- The thread will be unblocked with an `AsyncCancelled`-Exception, so
-- (contrary to the documentation) `closeFdWith` should not be necessary
-- when closing the fd.
threadWaitRead
fd
elapsed
<-
timerFdRead
timer
traceShowIO
elapsed
callback
setTimer
::
TimerFd
->
TimerSetTimeMode
->
CTimeSpec
->
IO
()
setTimer
timer
mode
timeSpec
=
setInterval
timer
mode
itspec
where
itspec
=
defaultCITimerSpec
{
it_value
=
timeSpec
}
setInterval
::
TimerFd
->
TimerSetTimeMode
->
CITimerSpec
->
IO
()
setInterval
timer
mode
iTimerSpec
=
do
alloca
\
newValue
->
do
poke
newValue
iTimerSpec
throwErrnoIfMinus1_
"timer_settime"
do
c_timerfd_settime
timer
0
newValue
nullPtr
disarm
::
TimerFd
->
IO
()
disarm
timer
=
setInterval
timer
TimeRelative
defaultCITimerSpec
timerFdRead
::
TimerFd
->
IO
Word64
timerFdRead
timer
=
do
alloca
\
ptr
->
do
throwErrnoIfMinus1
"timerfd_read"
do
c_timerfd_read
timer
ptr
8
peek
ptr
timerFdClose
::
TimerFd
->
IO
()
timerFdClose
timer
=
throwErrnoIfMinus1_
"timerfd_close"
$
c_timerfd_close
timer
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment