2009-04-13

MY_INIT


main里的入口
代码如下:

main的代码

// clien/mysql.cc
int main(int argc,char *argv[])
{
char buff[80];

MY_INIT(argv[0]);

...
}






include/my_sys.h line 40
MY_INIT
设置程序名字,并调用my_init()进行另外一些初始化
代码如下:

INIT的代码

#define MY_INIT(name); { my_progname= name; my_init(); }






my_init
代码见末尾.
1.检测init的状态,如果已经初始化完毕,或之前已经进行过初始化了,那么直接跳出.
2.设置初始化标记,表示初始化例程被调用过,即 1 中的 my_init_done标记.
3.递增初始化计数器.
4.设置默认的文件以及文件夹访问权限.
root用户以及所有者具有文件的读写权限,文件夹的所有权限
owner只具有文件的读写权限.
其余人没有任何权限
5.依据线程方面的一些开关
1)#if defined(THREAD) && defined(SAFE_MUTEX) /mysys/my_init.c line 80
进行名为safe_mutex_global_init 的操作
safe_mutex_global_init /mysys/thr_mutex.c line 50
|
|-- pthread_mutex_init /include/my_pthread line 236
|
|-- my_pthread_mutex_init /mysys/my_pthread.c 432
根据初始化互斥标记,进行互斥量的初始化
底层依靠的是 pthread 库的 pthread_mutex_init 函数
这段动作将初始化一个名为 THR_LOCK_mutex 的线程锁.
2)#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined (SAFE_MUTEX) /mysys/my_init.c line 83
进行名为fastmutex_global_init 的操作
设置了一个名为 cpu_count int类型静态量.
应该是CPU数量的计数器.
无其他任何动作.
根据线程方面的开关.在两个线程互斥模型中最多选择一个使用于系统.
注意到两个互斥的开关条件 defined(SAFE_MUTEX)
6.调用pthread的pthread_init初始化线程环境.
7.调用my_thread_global_init,并对此初始化例程的结果进行跟踪检测
函数动作包括
my_thread_global_init /mysys/my_thr_init.c line 81
1)调用get_thread_lib获得当前环境所使用的线程库类型.
线程库ID位于文件 /include/my_pthread.h line 691
2)利用pthread_keycreate建立一个新的线程上下文环境,并以THR_KEY_mysys作为此环境的索引
THR_KEY_mysys 类型未明. /mysys/my_thr_init.c line 86
3)判断是否在目标为linux环境
如果是,则在此版本的代码编写期间,pthread_exit函数存在race condition的bug.
使用一些代码避免这个bug
4)根据一些条件,做一些线程方面的设置工作.
主要牵涉到 pthread_mutexattr_init 和 pthread_mutexattr_settype 两个函数
5)初始化一些线程锁
名字列表:
THR_LOCK_malloc
THR_LOCK_open
THR_LOCK_lock
THR_LOCK_isam
THR_LOCK_myisam
THR_LOCK_heap
THR_LOCK_net
THR_LOCK_charset
THR_LOCK_threads
THR_LOCK_time
THR_COND_threads
注意到这些锁的行为由之前设定的一些attr决定.
6)调用pthread_cond_init函数
底层是pthread_cond_init,初始化名为THR_COND_threads的条件量
7)对于win平台,初始化一个THR_LOCK_thread
8)根据一些条件,有选择的初始化LOCK_localtime_r , LOCK_gethostbyname_r
9)调用my_thread_init,并检测状态.
获得之前建立的线程上下文环境,用THR_KEY_mysys索引,尝试得到一个上下文环境的指针.
然后将此数据结构放入用THR_KEY_mysys索引的上下文环境中.
数据结构为一个线程描述结构.
struct st_my_thread_var /include/my_pthread.h 662
10)如果没有异常,则进行扫尾工作.调用my_thread_global_end.
内部例程里利用线程锁,逐步等待线程结束.
清理之前申请的线程上下文环境 THR_KEY_mysys;
释放之前申请的所有的锁.参见 5)
8.对win环境读写一些注册表,并初始化winsock环境

代码如下:

my_init的代码

// mysys/my_init.c
my_bool my_init(void)
{
char * str;
if (my_init_done)
return 0;
my_init_done=1;
mysys_usage_id++;
my_umask= 0660; /* Default umask for new files */
my_umask_dir= 0700; /* Default umask for new directories */
#if defined(THREAD) && defined(SAFE_MUTEX)
safe_mutex_global_init(); /* Must be called early */
#endif
#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
fastmutex_global_init(); /* Must be called early */
#endif
netware_init();
#ifdef THREAD
#if defined(HAVE_PTHREAD_INIT)
pthread_init(); /* Must be called before DBUG_ENTER */
#endif
if (my_thread_global_init())
return 1;
#if !defined( __WIN__) && !defined(__NETWARE__)
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif
#endif /* THREAD */
{
DBUG_ENTER("my_init");
DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown"));
if (!home_dir)
{ /* Don't initialize twice */
my_win_init();
if ((home_dir=getenv("HOME")) != 0)
home_dir=intern_filename(home_dir_buff,home_dir);
#ifndef VMS
/* Default creation of new files */
if ((str=getenv("UMASK")) != 0)
my_umask=(int) (atoi_octal(str) 0600);
/* Default creation of new dir's */
if ((str=getenv("UMASK_DIR")) != 0)
my_umask_dir=(int) (atoi_octal(str) 0700);
#endif
#ifdef VMS
init_ctype(); /* Stupid linker don't link _ctype.c */
#endif
DBUG_PRINT("exit",("home: '%s'",home_dir));
}
#ifdef __WIN__
win32_init_tcp_ip();
#endif
DBUG_RETURN(0);
}
} /* my_init */


小结:
MY_INIT 宏所做的工作主要是:
1.初始化THR_KEY_mysys索引的线程环境.
2.初始化一些锁变量和线程条件变量.

没有评论:

发表评论

瑕不掩瑜

新加坡哪吒2终于上映了. 也终于有机会去看了. 客观地说, 剧本应该是还算可以的.但是叙事成熟度还是不太够. 虽然哪吒二阶重生的片段确实很打动人,但切割开来看的话,缺少一个比较明显的叙事主线. 或者说在剧情长短安排上还是有些不太平衡. 像第一关的土拨鼠. 作为一个单元片段放出来算...