poll 에서 사용하는 timeout 변수의 계산은 재 시작해야 하는 서비스의 시작 시간을 맞추기 위해서 입니다. 재 시작 할 서비스는 이전에 시작 한 시간에서 5 초 후에 재 시작을 해주는 룰을 적용하고 있습니다.
서비스가 시작되면 time_started 에 시작 시간을 지정합니다.
서비스의 시작은 service_start 함수에서 처리하며, 이 함수의 마지막 단계에서 서비스의 시작 시간을 gettime() 으로 지정합니다.
( gettime() 은 초 단위로 리턴합니다. )
svc->time_started = gettime();
다음은 init 의 메인 루프 코드 입니다.
여기서 중요한 것들은 restart_processes, process_needs_restart, timeout , wait_for_one_process 의 관계입니다.
for(;;) { if (process_needs_restart) { nr = poll(ufds, fd_count, timeout); if (ufds[2].revents == POLLIN) { |
서비스가 종료 되어, SIGCHLD 시그널을 받으면( 여러 논의가 있었지만 여기서는 이것만 주목 하겠습니다.)
wait_for_one_process 함수를 호출 합니다.
wait_for_one_process 에서 주목 할 점은 해당 서비스의 flags 에 SVC_RESTARTING 속성을 더합니다.
실제로 재 시작 시키지는 않습니다.
svc->flags |= SVC_RESTARTING;
이후 init 의 for 루프를 다시 돌아서 restart_processes 를 호출 합니다.
static void restart_processes() |
restart_processes 함수에서 process_needs_restart 변수를 0 으로 초기화 하고,
서비스 리스트 중에서 flags 에 SVC_RESTARTING 속성이 있는 것에 한해서 restart_service_if_needed 함수를 호출 합니다.
여기서 주목할 점은 링크드 리스트를 돈다는 것입니다. process_needs_restart 를 restart_service_if_needed 함수 내에서 설정 또는 변경 하는데, 모든 리스트가 다 돌고 난 후에 그 process_needs_restart 값이 init 에서 사용 됩니다.
static void restart_service_if_needed(struct service *svc) if (next_start_time <= gettime()) { if ((next_start_time < process_needs_restart) || |
restart_service_if_needed 함수에서는 svc->time_started 변수를 참조하는데, 이는 위에서도 설명 했듯이
서비스의 시작 시간 이였습니다. next_start_time 변수는 서비스가 이전에 시작 되었던 시간에서 5초를 더한 시간입니다.
결국 서비스가 재 시작 되어야 할 시간입니다. 서비스가 재 시작되어야 할 시간이 지났으면, service_start 함수를 호출해서 해당 서비스를 시작 시킴니다.
아직 재 시작 시킬 시간이 안되었다면, process_needs_restart 를 갱신하게 됩니다.
process_needs_restart 값이 초기값(0)이면, 지금 서비스의 재 시작 시간으로 갱신 되지만,
이 서비스 보다 링크드 리스트의 이전에 있던 서비스에 의해 갱신된 process_needs_restart 값을 가질 수도 있습니다.
그래서 지금 서비스의 재 시작 시간이 이전 서비스의 재 시작 시간보다 작으면, 지금 서비스의 재 시작 시간으로 process_needs_restart 를 갱신합니다.
결국 재시작 하려고 하는 서비스 중 가장 먼저 재 시작 되어야 할 시간으로 process_needs_restart 가 갱신 됩니다.
다시 init 으로 돌아 와서
if (process_needs_restart) { |
timeout 값은 재 시작 되어야 할 서비스들 중에서 가장 먼저 재 시작 할 서비스의 재 시작 시간 만큼을 위한 대기 시간이 지정됩니다.
그리고 그 값을 poll 의 timeout 으로 지정합니다. poll 의 timeout 발생후 다시 restart_processes 함수를 호출 하게 됩니다.
'안드로이드 > 플랫폼' 카테고리의 다른 글
service_manager 흐름 (0) | 2009.08.25 |
---|---|
init 분석 open 하는 디바이스 - null, kmsg (0) | 2009.08.18 |
init 분석 - firmware (0) | 2009.07.28 |
init 분석 - 안드로이드 보안 및 권한 (0) | 2009.07.28 |
프로세스, 기본 환경 (0) | 2009.07.28 |