1 // Copyright 2007, Google Inc.
2 
3 #ifndef TALK_BASE_MACSOCKETSERVER_H__
4 #define TALK_BASE_MACSOCKETSERVER_H__
5 
6 #include <set>
7 #ifdef OSX // Invalid on IOS
8 #include <Carbon/Carbon.h>
9 #endif
10 #include "talk/base/physicalsocketserver.h"
11 
12 namespace talk_base {
13 
14 ///////////////////////////////////////////////////////////////////////////////
15 // MacBaseSocketServer
16 ///////////////////////////////////////////////////////////////////////////////
17 class MacAsyncSocket;
18 
19 class MacBaseSocketServer : public PhysicalSocketServer {
20  public:
21   MacBaseSocketServer();
22   virtual ~MacBaseSocketServer();
23 
24   // SocketServer Interface
CreateSocket(int type)25   virtual Socket* CreateSocket(int type) { return NULL; }
CreateSocket(int family,int type)26   virtual Socket* CreateSocket(int family, int type) { return NULL; }
27 
28   virtual AsyncSocket* CreateAsyncSocket(int type);
29   virtual AsyncSocket* CreateAsyncSocket(int family, int type);
30 
31   virtual bool Wait(int cms, bool process_io) = 0;
32   virtual void WakeUp() = 0;
33 
34   void RegisterSocket(MacAsyncSocket* socket);
35   void UnregisterSocket(MacAsyncSocket* socket);
36 
37   // PhysicalSocketServer Overrides
38   virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
39 
40  protected:
41   void EnableSocketCallbacks(bool enable);
sockets()42   const std::set<MacAsyncSocket*>& sockets() {
43     return sockets_;
44   }
45 
46  private:
47   static void FileDescriptorCallback(CFFileDescriptorRef ref,
48                                      CFOptionFlags flags,
49                                      void* context);
50 
51   std::set<MacAsyncSocket*> sockets_;
52 };
53 
54 // Core Foundation implementation of the socket server. While idle it
55 // will run the current CF run loop. When the socket server has work
56 // to do the run loop will be paused. Does not support Carbon or Cocoa
57 // UI interaction.
58 class MacCFSocketServer : public MacBaseSocketServer {
59  public:
60   MacCFSocketServer();
61   virtual ~MacCFSocketServer();
62 
63   // SocketServer Interface
64   virtual bool Wait(int cms, bool process_io);
65   virtual void WakeUp();
66   void OnWakeUpCallback();
67 
68  private:
69   CFRunLoopRef run_loop_;
70   CFRunLoopSourceRef wake_up_;
71 };
72 
73 #ifdef OSX
74 
75 ///////////////////////////////////////////////////////////////////////////////
76 // MacCarbonSocketServer
77 ///////////////////////////////////////////////////////////////////////////////
78 
79 // Interacts with the Carbon event queue. While idle it will block,
80 // waiting for events. When the socket server has work to do, it will
81 // post a 'wake up' event to the queue, causing the thread to exit the
82 // event loop until the next call to Wait. Other events are dispatched
83 // to their target. Supports Carbon and Cocoa UI interaction.
84 class MacCarbonSocketServer : public MacBaseSocketServer {
85  public:
86   MacCarbonSocketServer();
87   virtual ~MacCarbonSocketServer();
88 
89   // SocketServer Interface
90   virtual bool Wait(int cms, bool process_io);
91   virtual void WakeUp();
92 
93  private:
94   EventQueueRef event_queue_;
95   EventRef wake_up_;
96 };
97 
98 ///////////////////////////////////////////////////////////////////////////////
99 // MacCarbonAppSocketServer
100 ///////////////////////////////////////////////////////////////////////////////
101 
102 // Runs the Carbon application event loop on the current thread while
103 // idle. When the socket server has work to do, it will post an event
104 // to the queue, causing the thread to exit the event loop until the
105 // next call to Wait. Other events are automatically dispatched to
106 // their target.
107 class MacCarbonAppSocketServer : public MacBaseSocketServer {
108  public:
109   MacCarbonAppSocketServer();
110   virtual ~MacCarbonAppSocketServer();
111 
112   // SocketServer Interface
113   virtual bool Wait(int cms, bool process_io);
114   virtual void WakeUp();
115 
116  private:
117   static OSStatus WakeUpEventHandler(EventHandlerCallRef next, EventRef event,
118                                      void *data);
119   static void TimerHandler(EventLoopTimerRef timer, void *data);
120 
121   EventQueueRef event_queue_;
122   EventHandlerRef event_handler_;
123   EventLoopTimerRef timer_;
124 };
125 
126 #endif
127 
128 ///////////////////////////////////////////////////////////////////////////////
129 // MacNotificationsSocketServer
130 ///////////////////////////////////////////////////////////////////////////////
131 
132 // The name "SocketServer" is misleading for this class. This class inherits
133 // from SocketServer, some variants of which create/use physical sockets
134 // (specifically, PhysicalSocketServer). But generally, this class is a way for
135 // a thread to schedule tasks (see task.h, thread.h and taskrunner.h).
136 //
137 // Since we don't want to write a custom Cocoa event loop, we will use this
138 // in a non-standard way. The "Wait" method will never actually wait - it will
139 // return false if cms > 0. Whenever a task needs to be woken up, the WakeUp
140 // method here will get called, and will cause the thread to cycle through all
141 // messages currently available.
142 
143 class MacNotificationsSocketServer : public SocketServer {
144  public:
145   MacNotificationsSocketServer();
146   virtual ~MacNotificationsSocketServer();
147 
148   // SocketServer Interface
CreateSocket(int type)149   virtual Socket* CreateSocket(int type) { return NULL; }
CreateAsyncSocket(int type)150   virtual AsyncSocket* CreateAsyncSocket(int type) { return NULL; }
151   // process_io argument is ignored.
152   virtual bool Wait(int cms, bool process_io);
153   virtual void WakeUp();
154 
155  private:
156   static void NotificationCallBack(CFNotificationCenterRef center,
157                                    void* observer,
158                                    CFStringRef name,
159                                    const void* object,
160                                    CFDictionaryRef userInfo);
161 
162   bool sent_notification_;
163 };
164 
165 ///////////////////////////////////////////////////////////////////////////////
166 
167 } // namespace talk_base
168 
169 #endif  // TALK_BASE_MACSOCKETSERVER_H__
170