00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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
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
00133 static status_t InitMain(const sptr<BProcess>& team = NULL);
00134 static status_t InitOther(const sptr<BProcess>& team = NULL);
00135
00136
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
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
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
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
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
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
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
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;
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;
00306 uint32_t m_signaled;
00307 SLocker m_signalLock;
00308
00309 #endif
00310 };
00311
00314 #if _SUPPORTS_NAMESPACE
00315 } }
00316 #endif
00317
00318 #endif