{- | Copyright : Will Thompson, Iñaki García Etxebarria and Jonas Platte License : LGPL-2.1 Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc) A 'GI.Gio.Objects.ThreadedSocketService.ThreadedSocketService' is a simple subclass of 'GI.Gio.Objects.SocketService.SocketService' that handles incoming connections by creating a worker thread and dispatching the connection to it by emitting the 'GI.Gio.Objects.ThreadedSocketService.ThreadedSocketService'::@/run/@ signal in the new thread. The signal handler may perform blocking IO and need not return until the connection is closed. The service is implemented using a thread pool, so there is a limited amount of threads available to serve incoming requests. The service automatically stops the 'GI.Gio.Objects.SocketService.SocketService' from accepting new connections when all threads are busy. As with 'GI.Gio.Objects.SocketService.SocketService', you may connect to 'GI.Gio.Objects.ThreadedSocketService.ThreadedSocketService'::@/run/@, or subclass and override the default handler. /Since: 2.22/ -} #define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \ && !defined(__HADDOCK_VERSION__)) module GI.Gio.Objects.ThreadedSocketService ( -- * Exported types ThreadedSocketService(..) , IsThreadedSocketService , toThreadedSocketService , noThreadedSocketService , -- * Methods -- ** new #method:new# threadedSocketServiceNew , -- * Properties -- ** maxThreads #attr:maxThreads# {- | /No description available in the introspection data./ -} #if ENABLE_OVERLOADING ThreadedSocketServiceMaxThreadsPropertyInfo, #endif constructThreadedSocketServiceMaxThreads, getThreadedSocketServiceMaxThreads , #if ENABLE_OVERLOADING threadedSocketServiceMaxThreads , #endif -- * Signals -- ** run #signal:run# C_ThreadedSocketServiceRunCallback , ThreadedSocketServiceRunCallback , #if ENABLE_OVERLOADING ThreadedSocketServiceRunSignalInfo , #endif afterThreadedSocketServiceRun , genClosure_ThreadedSocketServiceRun , mk_ThreadedSocketServiceRunCallback , noThreadedSocketServiceRunCallback , onThreadedSocketServiceRun , wrap_ThreadedSocketServiceRunCallback , ) where import Data.GI.Base.ShortPrelude import qualified Data.GI.Base.ShortPrelude as SP import qualified Data.GI.Base.Overloading as O import qualified Prelude as P import qualified Data.GI.Base.Attributes as GI.Attributes import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr import qualified Data.GI.Base.GClosure as B.GClosure import qualified Data.GI.Base.GError as B.GError import qualified Data.GI.Base.GVariant as B.GVariant import qualified Data.GI.Base.GValue as B.GValue import qualified Data.GI.Base.GParamSpec as B.GParamSpec import qualified Data.GI.Base.CallStack as B.CallStack import qualified Data.GI.Base.Properties as B.Properties import qualified Data.Text as T import qualified Data.ByteString.Char8 as B import qualified Data.Map as Map import qualified Foreign.Ptr as FP import qualified GHC.OverloadedLabels as OL import qualified GI.GObject.Objects.Object as GObject.Object import {-# SOURCE #-} qualified GI.Gio.Objects.SocketConnection as Gio.SocketConnection import {-# SOURCE #-} qualified GI.Gio.Objects.SocketListener as Gio.SocketListener import {-# SOURCE #-} qualified GI.Gio.Objects.SocketService as Gio.SocketService -- | Memory-managed wrapper type. newtype ThreadedSocketService = ThreadedSocketService (ManagedPtr ThreadedSocketService) foreign import ccall "g_threaded_socket_service_get_type" c_g_threaded_socket_service_get_type :: IO GType instance GObject ThreadedSocketService where gobjectType = c_g_threaded_socket_service_get_type -- | Type class for types which can be safely cast to `ThreadedSocketService`, for instance with `toThreadedSocketService`. class (GObject o, O.IsDescendantOf ThreadedSocketService o) => IsThreadedSocketService o instance (GObject o, O.IsDescendantOf ThreadedSocketService o) => IsThreadedSocketService o instance O.HasParentTypes ThreadedSocketService type instance O.ParentTypes ThreadedSocketService = '[Gio.SocketService.SocketService, Gio.SocketListener.SocketListener, GObject.Object.Object] -- | Cast to `ThreadedSocketService`, for types for which this is known to be safe. For general casts, use `Data.GI.Base.ManagedPtr.castTo`. toThreadedSocketService :: (MonadIO m, IsThreadedSocketService o) => o -> m ThreadedSocketService toThreadedSocketService = liftIO . unsafeCastTo ThreadedSocketService -- | A convenience alias for `Nothing` :: `Maybe` `ThreadedSocketService`. noThreadedSocketService :: Maybe ThreadedSocketService noThreadedSocketService = Nothing #if ENABLE_OVERLOADING type family ResolveThreadedSocketServiceMethod (t :: Symbol) (o :: *) :: * where ResolveThreadedSocketServiceMethod "accept" o = Gio.SocketListener.SocketListenerAcceptMethodInfo ResolveThreadedSocketServiceMethod "acceptAsync" o = Gio.SocketListener.SocketListenerAcceptAsyncMethodInfo ResolveThreadedSocketServiceMethod "acceptFinish" o = Gio.SocketListener.SocketListenerAcceptFinishMethodInfo ResolveThreadedSocketServiceMethod "acceptSocket" o = Gio.SocketListener.SocketListenerAcceptSocketMethodInfo ResolveThreadedSocketServiceMethod "acceptSocketAsync" o = Gio.SocketListener.SocketListenerAcceptSocketAsyncMethodInfo ResolveThreadedSocketServiceMethod "acceptSocketFinish" o = Gio.SocketListener.SocketListenerAcceptSocketFinishMethodInfo ResolveThreadedSocketServiceMethod "addAddress" o = Gio.SocketListener.SocketListenerAddAddressMethodInfo ResolveThreadedSocketServiceMethod "addAnyInetPort" o = Gio.SocketListener.SocketListenerAddAnyInetPortMethodInfo ResolveThreadedSocketServiceMethod "addInetPort" o = Gio.SocketListener.SocketListenerAddInetPortMethodInfo ResolveThreadedSocketServiceMethod "addSocket" o = Gio.SocketListener.SocketListenerAddSocketMethodInfo ResolveThreadedSocketServiceMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo ResolveThreadedSocketServiceMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo ResolveThreadedSocketServiceMethod "close" o = Gio.SocketListener.SocketListenerCloseMethodInfo ResolveThreadedSocketServiceMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo ResolveThreadedSocketServiceMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo ResolveThreadedSocketServiceMethod "getv" o = GObject.Object.ObjectGetvMethodInfo ResolveThreadedSocketServiceMethod "isActive" o = Gio.SocketService.SocketServiceIsActiveMethodInfo ResolveThreadedSocketServiceMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo ResolveThreadedSocketServiceMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo ResolveThreadedSocketServiceMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo ResolveThreadedSocketServiceMethod "ref" o = GObject.Object.ObjectRefMethodInfo ResolveThreadedSocketServiceMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo ResolveThreadedSocketServiceMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo ResolveThreadedSocketServiceMethod "start" o = Gio.SocketService.SocketServiceStartMethodInfo ResolveThreadedSocketServiceMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo ResolveThreadedSocketServiceMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo ResolveThreadedSocketServiceMethod "stop" o = Gio.SocketService.SocketServiceStopMethodInfo ResolveThreadedSocketServiceMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo ResolveThreadedSocketServiceMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo ResolveThreadedSocketServiceMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo ResolveThreadedSocketServiceMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo ResolveThreadedSocketServiceMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo ResolveThreadedSocketServiceMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo ResolveThreadedSocketServiceMethod "setBacklog" o = Gio.SocketListener.SocketListenerSetBacklogMethodInfo ResolveThreadedSocketServiceMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo ResolveThreadedSocketServiceMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo ResolveThreadedSocketServiceMethod l o = O.MethodResolutionFailed l o instance (info ~ ResolveThreadedSocketServiceMethod t ThreadedSocketService, O.MethodInfo info ThreadedSocketService p) => OL.IsLabel t (ThreadedSocketService -> p) where #if MIN_VERSION_base(4,10,0) fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #else fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #endif #endif -- signal ThreadedSocketService::run {- | The ::run signal is emitted in a worker thread in response to an incoming connection. This thread is dedicated to handling /@connection@/ and may perform blocking IO. The signal handler need not return until the connection is closed. -} type ThreadedSocketServiceRunCallback = Gio.SocketConnection.SocketConnection {- ^ /@connection@/: a new 'GI.Gio.Objects.SocketConnection.SocketConnection' object. -} -> GObject.Object.Object {- ^ /@sourceObject@/: the source_object passed to 'GI.Gio.Objects.SocketListener.socketListenerAddAddress'. -} -> IO Bool {- ^ __Returns:__ 'True' to stop further signal handlers from being called -} -- | A convenience synonym for @`Nothing` :: `Maybe` `ThreadedSocketServiceRunCallback`@. noThreadedSocketServiceRunCallback :: Maybe ThreadedSocketServiceRunCallback noThreadedSocketServiceRunCallback = Nothing -- | Type for the callback on the (unwrapped) C side. type C_ThreadedSocketServiceRunCallback = Ptr () -> -- object Ptr Gio.SocketConnection.SocketConnection -> Ptr GObject.Object.Object -> Ptr () -> -- user_data IO CInt -- | Generate a function pointer callable from C code, from a `C_ThreadedSocketServiceRunCallback`. foreign import ccall "wrapper" mk_ThreadedSocketServiceRunCallback :: C_ThreadedSocketServiceRunCallback -> IO (FunPtr C_ThreadedSocketServiceRunCallback) -- | Wrap the callback into a `GClosure`. genClosure_ThreadedSocketServiceRun :: MonadIO m => ThreadedSocketServiceRunCallback -> m (GClosure C_ThreadedSocketServiceRunCallback) genClosure_ThreadedSocketServiceRun cb = liftIO $ do let cb' = wrap_ThreadedSocketServiceRunCallback cb mk_ThreadedSocketServiceRunCallback cb' >>= B.GClosure.newGClosure -- | Wrap a `ThreadedSocketServiceRunCallback` into a `C_ThreadedSocketServiceRunCallback`. wrap_ThreadedSocketServiceRunCallback :: ThreadedSocketServiceRunCallback -> C_ThreadedSocketServiceRunCallback wrap_ThreadedSocketServiceRunCallback _cb _ connection sourceObject _ = do connection' <- (newObject Gio.SocketConnection.SocketConnection) connection sourceObject' <- (newObject GObject.Object.Object) sourceObject result <- _cb connection' sourceObject' let result' = (fromIntegral . fromEnum) result return result' {- | Connect a signal handler for the “@run@” signal, to be run before the default handler. When is enabled, this is equivalent to @ 'Data.GI.Base.Signals.on' threadedSocketService #run callback @ -} onThreadedSocketServiceRun :: (IsThreadedSocketService a, MonadIO m) => a -> ThreadedSocketServiceRunCallback -> m SignalHandlerId onThreadedSocketServiceRun obj cb = liftIO $ do let cb' = wrap_ThreadedSocketServiceRunCallback cb cb'' <- mk_ThreadedSocketServiceRunCallback cb' connectSignalFunPtr obj "run" cb'' SignalConnectBefore {- | Connect a signal handler for the “@run@” signal, to be run after the default handler. When is enabled, this is equivalent to @ 'Data.GI.Base.Signals.after' threadedSocketService #run callback @ -} afterThreadedSocketServiceRun :: (IsThreadedSocketService a, MonadIO m) => a -> ThreadedSocketServiceRunCallback -> m SignalHandlerId afterThreadedSocketServiceRun obj cb = liftIO $ do let cb' = wrap_ThreadedSocketServiceRunCallback cb cb'' <- mk_ThreadedSocketServiceRunCallback cb' connectSignalFunPtr obj "run" cb'' SignalConnectAfter -- VVV Prop "max-threads" -- Type: TBasicType TInt -- Flags: [PropertyReadable,PropertyWritable,PropertyConstructOnly] -- Nullable: (Nothing,Nothing) {- | Get the value of the “@max-threads@” property. When is enabled, this is equivalent to @ 'Data.GI.Base.Attributes.get' threadedSocketService #maxThreads @ -} getThreadedSocketServiceMaxThreads :: (MonadIO m, IsThreadedSocketService o) => o -> m Int32 getThreadedSocketServiceMaxThreads obj = liftIO $ B.Properties.getObjectPropertyInt32 obj "max-threads" {- | Construct a `GValueConstruct` with valid value for the “@max-threads@” property. This is rarely needed directly, but it is used by `Data.GI.Base.Constructible.new`. -} constructThreadedSocketServiceMaxThreads :: (IsThreadedSocketService o) => Int32 -> IO (GValueConstruct o) constructThreadedSocketServiceMaxThreads val = B.Properties.constructObjectPropertyInt32 "max-threads" val #if ENABLE_OVERLOADING data ThreadedSocketServiceMaxThreadsPropertyInfo instance AttrInfo ThreadedSocketServiceMaxThreadsPropertyInfo where type AttrAllowedOps ThreadedSocketServiceMaxThreadsPropertyInfo = '[ 'AttrConstruct, 'AttrGet] type AttrSetTypeConstraint ThreadedSocketServiceMaxThreadsPropertyInfo = (~) Int32 type AttrBaseTypeConstraint ThreadedSocketServiceMaxThreadsPropertyInfo = IsThreadedSocketService type AttrGetType ThreadedSocketServiceMaxThreadsPropertyInfo = Int32 type AttrLabel ThreadedSocketServiceMaxThreadsPropertyInfo = "max-threads" type AttrOrigin ThreadedSocketServiceMaxThreadsPropertyInfo = ThreadedSocketService attrGet _ = getThreadedSocketServiceMaxThreads attrSet _ = undefined attrConstruct _ = constructThreadedSocketServiceMaxThreads attrClear _ = undefined #endif #if ENABLE_OVERLOADING instance O.HasAttributeList ThreadedSocketService type instance O.AttributeList ThreadedSocketService = ThreadedSocketServiceAttributeList type ThreadedSocketServiceAttributeList = ('[ '("active", Gio.SocketService.SocketServiceActivePropertyInfo), '("listenBacklog", Gio.SocketListener.SocketListenerListenBacklogPropertyInfo), '("maxThreads", ThreadedSocketServiceMaxThreadsPropertyInfo)] :: [(Symbol, *)]) #endif #if ENABLE_OVERLOADING threadedSocketServiceMaxThreads :: AttrLabelProxy "maxThreads" threadedSocketServiceMaxThreads = AttrLabelProxy #endif #if ENABLE_OVERLOADING data ThreadedSocketServiceRunSignalInfo instance SignalInfo ThreadedSocketServiceRunSignalInfo where type HaskellCallbackType ThreadedSocketServiceRunSignalInfo = ThreadedSocketServiceRunCallback connectSignal _ obj cb connectMode = do let cb' = wrap_ThreadedSocketServiceRunCallback cb cb'' <- mk_ThreadedSocketServiceRunCallback cb' connectSignalFunPtr obj "run" cb'' connectMode type instance O.SignalList ThreadedSocketService = ThreadedSocketServiceSignalList type ThreadedSocketServiceSignalList = ('[ '("event", Gio.SocketListener.SocketListenerEventSignalInfo), '("incoming", Gio.SocketService.SocketServiceIncomingSignalInfo), '("notify", GObject.Object.ObjectNotifySignalInfo), '("run", ThreadedSocketServiceRunSignalInfo)] :: [(Symbol, *)]) #endif -- method ThreadedSocketService::new -- method type : Constructor -- Args : [Arg {argCName = "max_threads", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the maximal number of threads to execute concurrently\n handling incoming clients, -1 means no limit", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TInterface (Name {namespace = "Gio", name = "ThreadedSocketService"})) -- throws : False -- Skip return : False foreign import ccall "g_threaded_socket_service_new" g_threaded_socket_service_new :: Int32 -> -- max_threads : TBasicType TInt IO (Ptr ThreadedSocketService) {- | Creates a new 'GI.Gio.Objects.ThreadedSocketService.ThreadedSocketService' with no listeners. Listeners must be added with one of the 'GI.Gio.Objects.SocketListener.SocketListener' \"add\" methods. /Since: 2.22/ -} threadedSocketServiceNew :: (B.CallStack.HasCallStack, MonadIO m) => Int32 {- ^ /@maxThreads@/: the maximal number of threads to execute concurrently handling incoming clients, -1 means no limit -} -> m ThreadedSocketService {- ^ __Returns:__ a new 'GI.Gio.Objects.SocketService.SocketService'. -} threadedSocketServiceNew maxThreads = liftIO $ do result <- g_threaded_socket_service_new maxThreads checkUnexpectedReturnNULL "threadedSocketServiceNew" result result' <- (wrapObject ThreadedSocketService) result return result' #if ENABLE_OVERLOADING #endif