| // Copyright 2007, Google Inc. |
| |
| |
| #ifndef TALK_BASE_MACSOCKETSERVER_H__ |
| #define TALK_BASE_MACSOCKETSERVER_H__ |
| |
| #include <set> |
| #ifdef OSX // Invalid on IOS |
| #include <Carbon/Carbon.h> |
| #endif |
| #include "talk/base/physicalsocketserver.h" |
| |
| namespace talk_base { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // MacBaseSocketServer |
| /////////////////////////////////////////////////////////////////////////////// |
| class MacAsyncSocket; |
| |
| class MacBaseSocketServer : public PhysicalSocketServer { |
| public: |
| MacBaseSocketServer(); |
| virtual ~MacBaseSocketServer(); |
| |
| // SocketServer Interface |
| virtual Socket* CreateSocket(int type) { return NULL; } |
| virtual AsyncSocket* CreateAsyncSocket(int type); |
| virtual bool Wait(int cms, bool process_io) = 0; |
| virtual void WakeUp() = 0; |
| |
| void RegisterSocket(MacAsyncSocket* socket); |
| void UnregisterSocket(MacAsyncSocket* socket); |
| |
| // PhysicalSocketServer Overrides |
| virtual bool SetPosixSignalHandler(int signum, void (*handler)(int)); |
| |
| protected: |
| void EnableSocketCallbacks(bool enable); |
| const std::set<MacAsyncSocket*>& sockets() { |
| return sockets_; |
| } |
| |
| private: |
| static void FileDescriptorCallback(CFFileDescriptorRef ref, |
| CFOptionFlags flags, |
| void* context); |
| |
| std::set<MacAsyncSocket*> sockets_; |
| }; |
| |
| // Core Foundation implementation of the socket server. While idle it |
| // will run the current CF run loop. When the socket server has work |
| // to do the run loop will be paused. Does not support Carbon or Cocoa |
| // UI interaction. |
| class MacCFSocketServer : public MacBaseSocketServer { |
| public: |
| MacCFSocketServer(); |
| virtual ~MacCFSocketServer(); |
| |
| // SocketServer Interface |
| virtual bool Wait(int cms, bool process_io); |
| virtual void WakeUp(); |
| void OnWakeUpCallback(); |
| |
| private: |
| CFRunLoopRef run_loop_; |
| CFRunLoopSourceRef wake_up_; |
| }; |
| |
| #ifdef OSX |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // MacCarbonSocketServer |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| // Interacts with the Carbon event queue. While idle it will block, |
| // waiting for events. When the socket server has work to do, it will |
| // post a 'wake up' event to the queue, causing the thread to exit the |
| // event loop until the next call to Wait. Other events are dispatched |
| // to their target. Supports Carbon and Cocoa UI interaction. |
| class MacCarbonSocketServer : public MacBaseSocketServer { |
| public: |
| MacCarbonSocketServer(); |
| virtual ~MacCarbonSocketServer(); |
| |
| // SocketServer Interface |
| virtual bool Wait(int cms, bool process_io); |
| virtual void WakeUp(); |
| |
| private: |
| EventQueueRef event_queue_; |
| EventRef wake_up_; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // MacCarbonAppSocketServer |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| // Runs the Carbon application event loop on the current thread while |
| // idle. When the socket server has work to do, it will post an event |
| // to the queue, causing the thread to exit the event loop until the |
| // next call to Wait. Other events are automatically dispatched to |
| // their target. |
| class MacCarbonAppSocketServer : public MacBaseSocketServer { |
| public: |
| MacCarbonAppSocketServer(); |
| virtual ~MacCarbonAppSocketServer(); |
| |
| // SocketServer Interface |
| virtual bool Wait(int cms, bool process_io); |
| virtual void WakeUp(); |
| |
| private: |
| static OSStatus WakeUpEventHandler(EventHandlerCallRef next, EventRef event, |
| void *data); |
| static void TimerHandler(EventLoopTimerRef timer, void *data); |
| |
| EventQueueRef event_queue_; |
| EventHandlerRef event_handler_; |
| EventLoopTimerRef timer_; |
| }; |
| |
| #endif |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // MacNotificationsSocketServer |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| // The name "SocketServer" is misleading for this class. This class inherits |
| // from SocketServer, some variants of which create/use physical sockets |
| // (specifically, PhysicalSocketServer). But generally, this class is a way for |
| // a thread to schedule tasks (see task.h, thread.h and taskrunner.h). |
| // |
| // Since we don't want to write a custom Cocoa event loop, we will use this |
| // in a non-standard way. The "Wait" method will never actually wait - it will |
| // return false if cms > 0. Whenever a task needs to be woken up, the WakeUp |
| // method here will get called, and will cause the thread to cycle through all |
| // messages currently available. |
| |
| class MacNotificationsSocketServer : public SocketServer { |
| public: |
| MacNotificationsSocketServer(); |
| virtual ~MacNotificationsSocketServer(); |
| |
| // SocketServer Interface |
| virtual Socket* CreateSocket(int type) { return NULL; } |
| virtual AsyncSocket* CreateAsyncSocket(int type) { return NULL; } |
| // process_io argument is ignored. |
| virtual bool Wait(int cms, bool process_io); |
| virtual void WakeUp(); |
| |
| private: |
| static void NotificationCallBack(CFNotificationCenterRef center, |
| void* observer, |
| CFStringRef name, |
| const void* object, |
| CFDictionaryRef userInfo); |
| |
| bool sent_notification_; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| } // namespace talk_base |
| |
| #endif // TALK_BASE_MACSOCKETSERVER_H__ |