Looper.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_LOOPER_H
00014 #define _SUPPORT_LOOPER_H
00015 
00021 #include <support/Atom.h>
00022 #include <support/ConditionVariable.h>
00023 #include <support/SupportDefs.h>
00024 #include <support/IBinder.h>
00025 #include <support/Context.h>
00026 #include <support/Parcel.h>
00027 #if !LIBBE_BOOTSTRAP
00028 
00029 #endif
00030 #include <support/Process.h>
00031 #include <support/SortedVector.h>
00032 #include <stddef.h>
00033 
00034 #if TARGET_HOST == TARGET_HOST_LINUX
00035 #include <pthread.h>
00036 #endif
00037 
00038 #ifndef BINDER_DEBUG_LIB
00039 #define BINDER_DEBUG_LIB 0
00040 #endif
00041 
00042 #if _SUPPORTS_NAMESPACE
00043 namespace palmos {
00044 namespace support {
00045 #endif /* _SUPPORTS_NAMESPACE */
00046 
00047 class SParcel;
00048 class BSharedObject;
00049 struct handle_refs;
00050 
00052 SContext get_default_context();
00054 SContext get_system_context();
00055 
00056 SString get_system_directory();
00058 
00059 /*----------------------------------------------------------------*/
00060 /*----- SLooper class --------------------------------------------*/
00061 
00063 class SLooper
00064 {
00065     
00066     public:
00067 
00068         static  SLooper *               This();
00069         static  SLooper *               This(const sptr<BProcess>& team);
00070         
00071         static  void                    SetThreadPriority(int32_t priority);
00072         static  int32_t                 ThreadPriority();
00073         
00074         static  status_t                LastError();
00075         static  void                    SetLastError(status_t error);
00076         
00077         static  status_t                Loop(bool isMain);
00078         
00080 
00083         static  SysHandle               SpawnThread(    thread_func     function_name, 
00084                                                         const char      *thread_name, 
00085                                                         int32_t         priority, 
00086                                                         void            *arg);
00087         
00088         static  status_t                SpawnLooper();
00089         
00090         static  int32_t                 Thread();
00091         static  sptr<BProcess>          Process();
00092         static  int32_t                 ProcessID();
00093 
00095         static  bool                    SupportsProcesses();
00096         
00098 
00100         static  bool                    PrefersProcesses();
00101         
00103 
00111         static  void                    StopProcess(const sptr<IBinder>& rootObject, bool now=false);
00112     
00113         typedef status_t (*catch_root_func)(const sptr<IBinder>& node);
00114         static  void                    CatchRootObjects(catch_root_func func);
00115 #if TARGET_HOST == TARGET_HOST_LINUX
00116                 sptr<IBinder>           ReceiveRootObject(pid_t process);
00117 #endif // #if TARGET_HOST == TARGET_HOST_LINUX
00118                 status_t                SendRootObject(const sptr<IBinder>& rootNode);
00119 
00120         // Special boot-strap for the current environment.
00121         static  void                    SetContextObject(const sptr<IBinder>& object, const SString& name);
00122         static  sptr<IBinder>           GetContextObject(const SString& name, const sptr<IBinder>& caller);
00123         static  SContext                GetContext(const SString& name, const sptr<IBinder>& caller);
00124 
00125         static  sptr<IBinder>           GetStrongProxyForHandle(int32_t handle);
00126         static  wptr<IBinder>           GetWeakProxyForHandle(int32_t handle);
00127 
00128                 status_t                Transact(   int32_t handle,
00129                                                     uint32_t code, const SParcel& data,
00130                                                     SParcel* reply, uint32_t flags);
00131         
00132         // Only called by the main thread during static initialization
00133         static  status_t                InitMain(const sptr<BProcess>& team = NULL);
00134         static  status_t                InitOther(const sptr<BProcess>& team = NULL);
00135 
00136         // For use only by IBinder proxy object
00137                 status_t                IncrefsHandle(int32_t handle);
00138                 status_t                AcquireHandle(int32_t handle);
00139                 status_t                ReleaseHandle(int32_t handle);
00140                 status_t                DecrefsHandle(int32_t handle);
00141                 status_t                AttemptAcquireHandle(int32_t handle);
00142         static  status_t                ExpungeHandle(int32_t handle, IBinder* binder);
00143 
00144         // Special magic cleanup code for internal use.
00145         static  void                    Stop();
00146         static  void                    Shutdown();
00147 
00148                 void                    ExpungePackages();
00149 
00150 #if TARGET_HOST == TARGET_HOST_LINUX
00151         static  bool                    ProcessManagesContexts(void);
00152         
00153         typedef bool (*ContextPermissionCheckFunc)(const SString& name, const sptr<IBinder>& caller, void* userData);
00154         static  bool                    BecomeContextManager(ContextPermissionCheckFunc checkFunc, void* userData);
00155 #endif
00156 #if TARGET_HOST == TARGET_HOST_WIN32 || TARGET_HOST == TARGET_HOST_LINUX
00157                 SLooper*                GetNext();
00158                 void                    SetNext(SLooper* next);
00159         static  int32_t                 Loopers();
00160 #endif
00161 
00162     private:
00163     
00164         friend  class BProcess;
00165         friend  class BProcess::ComponentImage;
00166 
00167                 // --------------------------------------------------------------------
00168                 // The following methods have generic implementations for all platforms
00169                 // --------------------------------------------------------------------
00170 
00171                                         SLooper(const sptr<BProcess>& team = NULL);
00172                                         ~SLooper();
00173 
00174         static  void                    _DeleteSelf(void *blooper);
00175         static  bool                    _ResumingScheduling();
00176         static  void                    _ClearSchedulingResumed();
00177         static  int32_t                 _ThreadEntry(void *info);
00178         static  int32_t                 _Loop(SLooper *parent);
00179                 void                    _SetThreadPriority(int32_t priority);
00180 
00181         static  void                    _RegisterLooper(SLooper* who);
00182         static  bool                    _UnregisterLooper(SLooper* who);
00183         static  void                    _ShutdownLoopers();
00184         static  void                    _CleanupLoopers();
00185 
00186         static  int32_t                 TLS;
00187 
00188                 sptr<BProcess>          m_team;
00189                 team_id                 m_teamID;
00190 
00191                 int32_t                 m_thid;
00192                 int32_t                 m_priority;
00193                 int32_t                 m_flags;
00194                 status_t                m_lastError;
00195                 uint32_t                m_stackBottom;
00196                 SLooper*                m_nextRegistered;
00197 
00198                 SSortedVector< wptr<BProcess::ComponentImage> > m_dyingPackages;
00199 
00200                 // --------------------------------------------------------------------
00201                 // The following methods have platform-specific implementations.
00202                 // --------------------------------------------------------------------
00203 
00204                 void                    _ConstructPlatform();
00205                 void                    _DestroyPlatform();
00206                 status_t                _InitMainPlatform();
00207 
00208                 void                    _Signal();
00209                 void                    _Cleanup();
00210 
00211                 int32_t                 _LoopSelf();
00212 
00213                 sptr<IBinder>           _GetRootObject(SysHandle id, team_id team);
00214                 void                    _CatchRootObjects(catch_root_func func);
00215 
00216         static  bool                    _SetNextEventTime(nsecs_t when, int32_t priority);
00217 
00218 #if TARGET_HOST == TARGET_HOST_PALMOS
00219                 ptrdiff_t               _AvailStack(void) const;
00220 #endif
00221                 // --------------------------------------------------------------------
00222                 // Special methods and state for the BeOS platform.
00223                 // --------------------------------------------------------------------
00224 
00225 #if TARGET_HOST == TARGET_HOST_BEOS
00226         static  int32_t                 _DriverLoop(SLooper *parent);
00227 #if !BINDER_DEBUG_LIB
00228         static  int32_t                 _DriverLoopFromKernelLand(SLooper *parent);
00229 #endif /* !BINDER_DEBUG_LIB */
00230         static  status_t                _BufferReply(const SParcel& buffer, void* context);
00231         static  void                    _BufferFree(const void* data, ssize_t len, void* context);
00232         
00233                 status_t                _HandleCommand(int32_t cmd);
00234                 status_t                _WaitForCompletion( SParcel *reply = NULL,
00235                                                             status_t *acquireResult = NULL);
00236                 status_t                _WriteTransaction(  int32_t cmd, uint32_t binderFlags,
00237                                                             int32_t handle, uint32_t code,
00238                                                             const SParcel& data,
00239                                                             status_t* statusBuffer = NULL);
00240                 status_t                _Reply(uint32_t flags, const SParcel& reply);
00241                 status_t                _TransactWithDriver(bool doRead = true);
00242 
00243                 int32_t                 m_binderDesc;
00244                 SParcel                 m_in;
00245                 SParcel                 m_out;
00246 
00247                 // --------------------------------------------------------------------
00248                 // Special methods and state for the PalmOS platform.
00249                 // --------------------------------------------------------------------
00250 
00251 #elif TARGET_HOST == TARGET_HOST_PALMOS
00252         static  status_t                _SpawnTransactionLooper(char code);
00253         static  int32_t                 _EnterTransactionLoop(BProcess *team);
00254                 int32_t                 _LoopTransactionSelf();
00255         static  int32_t                 _EnterLoop(BProcess *team);
00256                 status_t                _HandleResponse(KALBinderIPCArgsType *ioSndArgs, uint8_t *meta, SParcel *reply, bool spawnLoopers = false);
00257         static  sptr<IBinder>           _RetrieveContext(uint32_t which, KeyID permissionKey);
00258                 ThreadExitCallbackID    m_exitCallback;
00259                 KeyID                   m_keys[MAX_KEY_TRANSFER];
00260 
00261 #elif TARGET_HOST == TARGET_HOST_WIN32
00262                 // --------------------------------------------------------------------
00263                 // Special methods and state for the Windows platform.
00264                 // --------------------------------------------------------------------
00265 
00266         static  int32_t                 _EnterLoop(SLooper *parent);
00267 
00268                 bool                    m_spawnedInternally : 1;
00269                 bool                    m_rescheduling : 1;
00270                 nsecs_t                 m_idleTime;
00271                 nsecs_t                 m_lastTimeISlept;
00272                 SLocker                 m_teamLock;
00273                 SLooper*                m_next;         // This pointer is owned by the team.
00274                 uint32_t                m_signaled;
00275                 SLocker                 m_signalLock;
00276 
00277 #elif TARGET_HOST == TARGET_HOST_LINUX
00278 
00279         static  int32_t                 _EnterLoop(SLooper *parent);
00280         static  status_t                _BufferReply(const SParcel& buffer, void* context);
00281         static  void                    _BufferFree(const void* data, ssize_t len, void* context);
00282         static  sptr<IBinder>           _RetrieveContext(const SString& name, const sptr<IBinder>& caller);
00283         
00284                 status_t                _HandleCommand(int32_t cmd);
00285                 status_t                _WaitForCompletion( SParcel *reply = NULL,
00286                                                             status_t *acquireResult = NULL);
00287                 status_t                _WriteTransaction(  int32_t cmd, uint32_t binderFlags,
00288                                                             int32_t handle, uint32_t code,
00289                                                             const SParcel& data,
00290                                                             status_t* statusBuffer = NULL);
00291                 status_t                _Reply(uint32_t flags, const SParcel& reply);
00292                 status_t                _TransactWithDriver(bool doRead = true);
00293 
00294                 SParcel                 m_in;
00295                 SParcel                 m_out;
00296 
00297 
00298                 bool                    m_spawnedInternally : 1;
00299                 bool                    m_rescheduling : 1;
00300                 pthread_cond_t          m_condition;
00301                 pthread_mutex_t         m_mutex;
00302                 nsecs_t                 m_idleTime;
00303                 nsecs_t                 m_lastTimeISlept;
00304                 SLocker                 m_teamLock;
00305                 SLooper*                m_next;         // This pointer is owned by the team.
00306                 uint32_t                m_signaled;
00307                 SLocker                 m_signalLock;
00308 
00309 #endif
00310 };
00311 
00314 #if _SUPPORTS_NAMESPACE
00315 } } // namespace palmos::support
00316 #endif /* _SUPPORTS_NAMESPACE */
00317 
00318 #endif /* _SUPPORT_LOOPER_H */