📄 symbian_os.cpp
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / common tools sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <gpac/tools.h>#include <gpac/network.h>#ifdef __SYMBIAN32__#include <time.h>#include <sys/stat.h>#include <sys/time.h>#include <dirent.h>#include <unistd.h>#include <sys/times.h>#include <sys/resource.h>/*symbian stdlib*/#include <e32std.h> /*symbian core (for scheduler & trap cleanup)*/#include <e32base.h> /*hardware abstraction layer*/#include <hal.h> /*gpac module internals*/#include "module_wrap.h"#include <gpac/thread.h> // Exported Functions (DLL entry point)#ifndef EKA2 // for EKA1 onlyEXPORT_C TInt E32Dll(TDllReason /*aReason*/)// Called when the DLL is loaded and unloaded. Note: have to define// epoccalldllentrypoints in MMP file to get this called in THUMB.{ return KErrNone;}#endif#define SLEEP_ABS_SELECT 1static u32 sys_start_time = 0;GF_EXPORTu32 gf_sys_clock(){ struct timeval now; gettimeofday(&now, NULL); return ( (now.tv_sec)*1000 + (now.tv_usec) / 1000) - sys_start_time;}GF_EXPORTvoid gf_sleep(u32 ms){ TTimeIntervalMicroSeconds32 inter; inter = (TInt) (1000*ms); User::AfterHighRes(inter); #if 0 TInt error; CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); RTimer timer; TRequestStatus timerStatus; timer.CreateLocal(); timer.After(timerStatus,ms*1000); User::WaitForRequest(timerStatus); #endif}GF_EXPORTvoid gf_delete_file(char *fileName){ remove(fileName);}GF_EXPORTvoid gf_rand_init(Bool Reset){ if (Reset) { srand(1); } else { srand( (u32) time(NULL) ); }}GF_EXPORTu32 gf_rand(){ return rand();}#ifndef GPAC_READ_ONLYGF_EXPORTFILE *gf_temp_file_new(){ return tmpfile(); }#endifGF_EXPORTvoid gf_utc_time_since_1970(u32 *sec, u32 *msec){ struct timeval tv; gettimeofday(&tv, NULL); *sec = tv.tv_sec; *msec = tv.tv_usec/1000;}GF_EXPORTvoid gf_get_user_name(char *buf, u32 buf_size){ strcpy(buf, "mpeg4-user");#if 0 s32 len; char *t; strcpy(buf, ""); len = 1024; GetUserName(buf, &len); if (!len) { t = getenv("USER"); if (t) strcpy(buf, t); }#endif#if 0 struct passwd *pw; pw = getpwuid(getuid()); strcpy(buf, ""); if (pw && pw->pw_name) strcpy(name, pw->pw_name);#endif}GF_EXPORTchar * my_str_upr(char *str){ u32 i; for (i=0; i<strlen(str); i++) { str[i] = toupper(str[i]); } return str;}GF_EXPORTchar * my_str_lwr(char *str){ u32 i; for (i=0; i<strlen(str); i++) { str[i] = tolower(str[i]); } return str;}/*enumerate directories*/GF_EXPORTGF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item enum_dir_fct, void *cbck, const char *filter){ unsigned char item_path[GF_MAX_PATH]; unsigned char path[GF_MAX_PATH], *file; DIR *the_dir; struct dirent* the_file; struct stat st; if (!dir || !enum_dir_fct) return GF_BAD_PARAM; strcpy((char*)path, dir); if (path[strlen((const char*)path)-1] != '\\') strcat((char*)path, "\\"); the_dir = opendir((char*)path); if (the_dir == NULL) return GF_IO_ERR; the_file = readdir(the_dir); while (the_file) { if (!strcmp(the_file->d_name, "..")) goto next; if (the_file->d_name[0] == '.') goto next; if (filter) { char ext[30]; char *sep = strrchr(the_file->d_name, '.'); if (!sep) goto next; strcpy(ext, sep+1); strlwr(ext); if (!strstr(filter, sep+1)) goto next; } strcpy((char*)item_path, (const char*)path); strcat((char*)item_path, the_file->d_name); if (stat( (const char*)item_path, &st ) != 0) goto next; if (enum_directory && ( (st.st_mode & S_IFMT) != S_IFDIR)) goto next; if (!enum_directory && ((st.st_mode & S_IFMT) == S_IFDIR)) goto next; file = (unsigned char*)the_file->d_name; if (enum_dir_fct(cbck, (char *)file, (char *)item_path)) { break; }next: the_file = readdir(the_dir); } return GF_OK;}GF_EXPORTu64 gf_f64_tell(FILE *fp){ return (u64) ftell(fp);}GF_EXPORTu64 gf_f64_seek(FILE *fp, s64 offset, s32 whence){ return fseek(fp, (s32) offset, whence);}GF_EXPORTFILE *gf_f64_open(const char *file_name, const char *mode){ return fopen(file_name, mode);}/*symbian thread*/typedef RThread* TH_HANDLE;/********************************************************************* OS-Specific Thread Object**********************************************************************/struct __tag_thread{ u32 status; TH_HANDLE threadH; u32 stackSize; /* the thread procedure */ u32 (*Run)(void *param); void *args; /* lock for signal */ GF_Semaphore *_signal;};GF_EXPORTGF_Thread *gf_th_new(){ GF_Thread *tmp = (GF_Thread *) malloc(sizeof(GF_Thread)); memset((void *)tmp, 0, sizeof(GF_Thread)); tmp->status = GF_THREAD_STATUS_STOP; return tmp;}#if 0static void *RunThread(void *ptr){ u32 ret = 0; GF_Thread *t = (GF_Thread *)ptr; GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Thread 0x%08x start\n", t->threadH->Handle() )); /* Signal the caller */ t->status = GF_THREAD_STATUS_RUN; gf_sema_notify(t->_signal, 1); /* Run our thread */ ret = t->Run(t->args); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Thread 0x%08x exit\n", t->threadH->Handle() )); t->status = GF_THREAD_STATUS_DEAD; t->Run = NULL; t->threadH->Close(); t->threadH = NULL; return (void *)ret;}#elsestatic void *RunThread(void *ptr){ TInt err; u32 ret = 0; CTrapCleanup * cleanup = NULL; GF_Thread *t = (GF_Thread *)ptr; GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Thread 0x%08x start\n", t->threadH->Handle() ));#if 1 GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[core] Creating new ActiveScheduler for thread\n")); CActiveScheduler * scheduler = new CActiveScheduler(); if (scheduler == NULL) { t->status = GF_THREAD_STATUS_DEAD; gf_sema_notify(t->_signal, 1); goto exit; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[core] Installing ActiveScheduler for thread\n")); CActiveScheduler::Install(scheduler);#endif GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[core] Creating cleanup trap for thread\n")); cleanup = CTrapCleanup::New(); if( cleanup == NULL ) { t->status = GF_THREAD_STATUS_DEAD; gf_sema_notify(t->_signal, 1); delete CActiveScheduler::Current(); goto exit; }#if 0 GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[core] Starting scheduler for thread\n")); CActiveScheduler::Start();#endif /* OK , signal the caller */ t->status = GF_THREAD_STATUS_RUN; gf_sema_notify(t->_signal, 1); /* Run our thread */ GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[core] Executing thread body\n")); TRAP(err, ret=t->Run(t->args) ); //ret = t->Run(t->args); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] destroying current ActiveScheduler\n")); delete CActiveScheduler::Current(); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] destroying trap cleanup\n")); delete cleanup;exit: GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Thread 0x%08x exit\n", t->threadH->Handle() )); t->status = GF_THREAD_STATUS_DEAD; t->Run = NULL; t->threadH->Close(); t->threadH = NULL; return (void *)ret;}#endifGF_EXPORTGF_Err gf_th_run(GF_Thread *t, u32 (*Run)(void *param), void *param){ TBuf<32> threadName; const TUint KThreadMinHeapSize = 0x1000; const TUint KThreadMaxHeapSize = 0x10000; if (!t || t->Run || t->_signal) return GF_BAD_PARAM; t->Run = Run; t->args = param; t->_signal = gf_sema_new(1, 0); if (! t->_signal) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Unable to create thread start-up semaphore\n")); t->status = GF_THREAD_STATUS_DEAD; return GF_IO_ERR; } threadName.Format(_L("GTH%d"), (u32) t); t->threadH = new RThread(); if ( t->threadH->Create(threadName, (TThreadFunction)RunThread, KDefaultStackSize, KThreadMinHeapSize, KThreadMaxHeapSize, (void *)t, EOwnerProcess) != KErrNone){ GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Unable to create thread\n")); t->status = GF_THREAD_STATUS_DEAD; return GF_IO_ERR; } t->threadH->Resume(); /*wait for the child function to call us - do NOT return before, otherwise the thread status would be unknown*/ //GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Waiting for thread to start\n")); gf_sema_wait(t->_signal); gf_sema_del(t->_signal); t->_signal = NULL; return GF_OK;}/* Stops a thread. If Destroy is not 0, thread is destroyed DANGEROUS as no cleanup */static void Thread_Stop(GF_Thread *t, Bool Destroy){ if (gf_th_status(t) == GF_THREAD_STATUS_RUN) { if (Destroy){ t->threadH->Terminate(0); t->threadH = NULL; } else{ t->threadH->Suspend(); } } t->status = GF_THREAD_STATUS_DEAD;}GF_EXPORTvoid gf_th_stop(GF_Thread *t)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -