++++++++++++++++++++++++++
+ Header File
++++++++++++++++++++++++++
// posix_proactor.h, v 0.1 2005/05/19
// ============================================================================
/**
*
*
*
* @file posix_proactor.h
*
* @brief posix_proactor which use RT Signal.
*
* struct aiocb
* int aio_fildes; //file descriptor
* volatile void *aio_buf; //buffer allocation
* size_t aio_nbytes; //length of transfer
* off_t aio_offet; //file offset. starting position
* int aio_reqprio; //request priority offset(_POSIX_PRIORITIZED_IO and _POSIX_PRORITY_SCHEDULING
* struct sigevent aio_sigevent; //signal number and offset
* int aio_lio_opcode; //listio operation
*
* @author sunsson <sunsson@varovision.com>
*/
// ============================================================================
#ifndef __POSIX_PROACTOR__
#define __POSIX_PROACTOR__
#include <signal.h>
#include <time.h>
#include <aio.h>
#define AIOCB_MAX_SIZE 2048 //서버가 지원하는 최대 클라이언트 수(1024) * 클라이언트 당 요청한 파일의 미디어 수(평균 2)
#define PROACTOR_DEBUG 1
#ifdef __cplusplus
extern "C" {
#endif//__cplusplus
//typedef void (*SIGNAL_C_FUNC)(int, siginfo_t *, void *);
/**
* posix asynchronous result
* <BR>
* asynchronous reqeust를 요청한 곳 ( handler, data ) 에 요청된 결과가 처리되었을 때
* 알리기 위한 구조
*/
typedef struct posix_asynch_result{
/// allocated aiocb
struct aiocb *aiocb;
/// file description
int fd;
/// Bytes transferred by this operation.
size_t size;
/**
* This really make sense only when doing file I/O.
*
* @@ On POSIX4-Unix, offset_high should be supported using
* aiocb64.
*
*/
unsigned long offset;
unsigned long offset_high;
/// Priority of the operation.
int priority;
/**
* POSIX4 realtime signal number to be used for the
* operation. <signal_number> ranges from SIGRTMIN to SIGRTMAX. By
* default, SIGRTMIN is used to issue <aio_> calls.
*/
int signal_number;
/// Success indicator.
int success;
/// Error if operation failed.
unsigned long error;
/// on receiving signal in signal_hander, to call media's handler function
void * (*hndlr)(void *);
/// on receiving signal in signal_hander, to give a parameter to media's handler function
void * data;
}posix_asynch_result;
/**
* aiocb에 대한 요청이 READ인지, WRITE인지를 나타내는 값
*/
typedef enum{
READ = 1,
WRITE = 2
}Opcode;
/// number of aiocb
struct aiocb **aiocb_list; //AIOCB_MAX_SIZE만큼
posix_asynch_result **result_list;
/// signal set
static sigset_t RT_completion_signal;
/// To maintain the maximum size of the array (list).
size_t aiocb_list_max_size;
/// To maintain the current size of the array (list).
size_t aiocb_list_cur_size;
/// Number of posix_asynch_result's waiting for start
/// i.e. deferred AIOs
size_t num_deferred_aiocb;
/// Number active,i.e. running requests
size_t num_started_aio;
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////PROACTOR INIT////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/**
* @author 박학선
* @param max_aio_operations System Interface에서 사용할 aiocb_list의 최대 갯수
* @retval -1 proactor init error
* @retval 0 proactor init ok
* @brief System Interface이 초기화될 때 posix_proactor를 초기화
* 하면서 시그널 세팅!!
*/
int
posix_proactor_init(size_t max_aio_operations);
/**
* @author 박학선
* @param
* @retval
* @brief System의 max aio size를 체크!!
*/
void
check_max_aio_num();
/**
* @author 박학선
* @param
* @retval 0 result create ok
* @brief System이 관리할 aiocb_list, result_list를 만듬
*/
int
create_result_aiocb_list();
/**
* @author 박학선
* @param
* @retval -1 setup signal init or setup signal_hanlder fail
* @retval 0 setup signal init(handler) success
* @brief System이 사용할 signal(RTSIG_MIN) set up!!
*/
int
signal_init();
/**
* @author 박학선
* @param signal_number signal handler를 띄울 RTSIG
* @retval -1 setup signal handler fail
* @retval 0 setup signal handler success
* @brief System Interface이 초기화될 때 시그널 핸들러 세팅!!
*/
int
setup_signal_handler(int signal_number);
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////CALLBACK/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/**
* @author 박학선
* @param signal_number signal handler를 깨운 signal
* @param info signal과 연관된 정보들(aiocb_list의 index)
* @param context 사용한 바 없음.
* @retval
* @brief 요청된 read를 수행한 후에 호출되는 signal_handler
*/
void
rtsig_handler (int signal_number, siginfo_t* info, void* context);
/**
* @author 박학선
* @param
* @retval -1 handler event error
* @retval 0 run_event_loop complete
* @brief loop을 돌면서 완료된 aiocb_list가 있는지 검사
*/
int
run_event_loop();
/**
* @author 박학선
* @param
* @retval -1 sigtimedwait error
* @retval 0 handler_event complete
* @brief 요청된 read를 수행한 후에 호출되는 signal_handler
* ====> signal_handler에서 signal을 감지했을 때완료된 요청이 있는지 검사
*/
int
handle_event(void);
//posix_asynch_result *
//find_completed_aio(int *error_status, size_t *transfer_count, size_t index, size_t count);
/**
* @author 박학선
* @param aiocb
* @param error_status
* @param transfer_count
* @retval 1 AIO completed
* @retval 0 not completed yet
* @brief AIO가 completed되었는지를 체크
*/
int
get_result_status (struct aiocb *aiocb, int *error_status, size_t *transfer_count);
/**
* @author 박학선
* @param idx
* @param transfer_count
* @param error_status
* @brief completed된 aiocb_list의 callback handler를 호출
*/
void
application_specific_code(size_t idx, int transfer_count, int error_status);
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////REQEUEST////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/**
* @author 박학선
* @param file_fd
* @param size
* @param offset
* @param buf
* @param data
* @param hndlr_ftn
* @param priority
* @param op
* @brief media에서 asynchronous read를 요청하기 위해 호출하는 함수.
* 실제로는 이 파일안에 정의되어 있지는 않음. 단지 테스트를 위해서...
*/
int
si_read_req(int file_fd, int size, int offset, void *buf, void *data, void *hndlr_ftn, int priority, Opcode op);
/**
* @author 박학선
* @param result
* @param op
* @retval 0 started OK
* @retval 1 OS AIO queue overflow
* @retval -1 do not started
* @brief System Interface(si_read_req())에서 Proactor에
* read를 요청하기 위해 사용!!
*/
int
issue_aio_calls (posix_asynch_result *result, Opcode op);
/**
* @author 박학선
* @param aiocb
* @retval 0 AIO was started successfully
* @retval 1 AIO was not started, OS AIO queue overflow
* @retval -1 AIO was not started, other errors
* @brief 파일의 미디어 트랙에서 aio_read, aio_write를 실행!!
*/
int
execute_aio_calls (struct aiocb * aiocb);
/**
* @author 박학선
* @param aiocb
* @retval retval > 0 allocated aiocb_list's slot
* @retval -1 no free slot
* @brief 이 시스템에서 관리하는 aiocb_list의 free slot을 반환한다.
*/
ssize_t
allocate_aio_slot(struct aiocb * aiocb);
#ifdef __cplusplus
}
#endif//__cplusplus
#endif //__POSIX_PROACTOR__
++++++++++++++++++++++++++
+ Source File
++++++++++++++++++++++++++
// posix_proactor.c, v 0.1 2005/05/19
// ============================================================================
/**
*
*
*
* @file posix_proactor.c
*
* posix_proactor which use RT Signal.
*
* struct aiocb
* int aio_fildes; //file descriptor
* volatile void *aio_buf; //buffer allocation
* size_t aio_nbytes; //length of transfer
* off_t aio_offet; //file offset. starting position
* int aio_reqprio; //request priority offset(_POSIX_PRIORITIZED_IO and _POSIX_PRORITY_SCHEDULING
* struct sigevent aio_sigevent; //signal number and offset
* int aio_lio_opcode; //listio operation
*
* @author sunsson <sunsson@varovision.com>
*/
// ============================================================================
#include "posix_proactor.h"
#include "test/test_posix_proactor.h"
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h> //getrlimit, strlimit : control maximum resource consumption
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <limits.h>
#include <aio.h>
#include <time.h>
#include <assert.h>
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////PROACTOR INIT////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/**
* @author 박학선
* @param max_aio_operations System Interface에서 사용할 aiocb_list의 최대 갯수
* @retval -1 proactor init error
* @retval 0 proactor init ok
* @brief System Interface이 초기화될 때 posix_proactor를 초기화
* 하면서 시그널 세팅!!
*/
int
posix_proactor_init(size_t max_aio_operations)
{
aiocb_list = 0;
result_list = 0;
aiocb_list_max_size = max_aio_operations;
aiocb_list_cur_size = 0;
num_deferred_aiocb = 0;
num_started_aio = 0;
check_max_aio_num();
if(create_result_aiocb_list() != 0){
fprintf(stderr, "aiocb list make error\n");
return -1;
}
if(signal_init() != 0){
fprintf(stderr, "signal init error\n");
return -1;
}
///run_event_loop에서 완료된 sigset이 있는지 체크..
//run_event_loop();
return 0;
}
/**
* @author 박학선
* @param
* @retval
* @brief System의 max aio size를 체크!!
*/
void
check_max_aio_num()
{
long max_aio_num;
int max_num_files, r;
struct rlimit rl;
max_aio_num = sysconf (_SC_AIO_MAX);
if (max_aio_num > 0 && aiocb_list_max_size > (unsigned long) max_aio_num)
aiocb_list_max_size = max_aio_num;
if (aiocb_list_max_size <= 0 || aiocb_list_max_size > AIOCB_MAX_SIZE)
aiocb_list_max_size = AIOCB_MAX_SIZE;
#if defined (RLIM_INFINITY)
r = getrlimit (RLIMIT_NOFILE, &rl);
if (r == 0 && rl.rlim_cur != RLIM_INFINITY)
max_num_files = rl.rlim_cur;
#endif //RLIM_INFINITY
if (max_num_files > 0 && aiocb_list_max_size > (unsigned long) max_num_files){
#if defined (RLIM_INFINITY)
rl.rlim_cur = max_num_files;
r = setrlimit (RLIMIT_NOFILE, &rl);
if (r == 0 && rl.rlim_cur != RLIM_INFINITY)
#endif //RLIM_INFINITY
aiocb_list_max_size = max_num_files;
}
}
/**
* @author 박학선
* @param
* @retval 0 result create ok
* @brief System이 관리할 aiocb_list, result_list를 만듬
*/
int create_result_aiocb_list()
{
size_t ai;
if (aiocb_list != 0)
return 0;
aiocb_list = (struct aiocb**)malloc(sizeof(struct aiocb *[aiocb_list_max_size]));
result_list = (posix_asynch_result **)malloc(sizeof(posix_asynch_result * [aiocb_list_max_size]));
for (ai = 0; ai < aiocb_list_max_size; ai++){
aiocb_list[ai] = 0;
result_list[ai] = 0;
}
return 0;
}
/**
* @author 박학선
* @param
* @retval -1 setup signal init or setup signal_hanlder fail
* @retval 0 setup signal init(handler) success
* @brief System이 사용할 signal(RTSIG_MIN) set up!!
*/
int signal_init()
{
int ret_val;
/// Get full set
if(sigemptyset(&RT_completion_signal) == -1)
fprintf(stderr, "[Error] Couldnt empty signal set\n");
if(sigaddset(&RT_completion_signal, SIGRTMIN) == -1)
fprintf(stderr, "[Error] Couldnt init the RT completion signal set\n");
///block the signal
if(sigprocmask(SIG_BLOCK, &RT_completion_signal, 0) == -1) {
fprintf(stderr, "Could not block SIGRTMAX or SIGRTMAX-1");
return -1;
}
ret_val = setup_signal_handler(SIGRTMIN);
///unblock the signal
//if(sigprocmask(SIG_UNBLOCK, &newact.sa_mask, NULL) == -1){
if(sigprocmask(SIG_UNBLOCK, &RT_completion_signal, 0) == -1) {
fprintf(stderr, "Could not unblock SIGRTMAX or SIGRTMAX-1");
return -1;
}
return ret_val;
}
/**
* @author 박학선
* @param signal_number signal handler를 띄울 RTSIG
* @retval -1 setup signal handler fail
* @retval 0 setup signal handler success
* @brief System Interface이 초기화될 때 시그널 핸들러 세팅!!
*/
int
setup_signal_handler(int signal_number)
{
struct sigaction newact;
int sigaction_return;
sigemptyset(&newact.sa_mask); //Nothing else to mask
newact.sa_flags = SA_SIGINFO; // Realtime flag.
newact.sa_sigaction = rtsig_handler ; //set up "null_handler"
sigaction_return = sigaction (signal_number, &newact, 0); //specify the action to be associated with a specific signal
if(sigaction_return == -1){
fprintf(stderr, "[Error]couldnt do sigaction for the RT SIGNAL\n");
return -1;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////CALLBACK/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/**
* @author 박학선
* @param signal_number signal handler를 깨운 signal
* @param info signal과 연관된 정보들(aiocb_list의 index)
* @param context 사용한 바 없음.
* @retval
* @brief 요청된 read를 수행한 후에 호출되는 signal_handler
*/
void
rtsig_handler (int signal_number, siginfo_t* info, void* context)
{
int result = 0;
// struct timespec timeout;
#if 0
fprintf(stderr, "[info]Signal number %d\n", signal_number);
if(query_aio_completions() < 0)
fprintf(stderr, "null handler error\n");
else
fprintf(stdout, "rtsig_handler\n");
#else//0
#ifdef PROACTOR_DEBUG
fprintf(stdout, "\n\nrtsig_handler\n");
#endif//PROACTOR_DEBUG
result = handle_event ();
if (result != 0 || errno == ETIME)
perror("handle_event \n");
#endif//0
exit(1);
}
/**
* @author 박학선
* @param
* @retval -1 handler event error
* @retval 0 run_event_loop complete
* @brief loop을 돌면서 완료된 aiocb_list가 있는지 검사
*/
int run_event_loop()
{
int ret_val;
// Run the event loop.
for (;;){
ret_val = handle_event();
if(ret_val == -1)
break;
}
return 0;
}
/**
* @author 박학선
* @param
* @retval -1 sigtimedwait error
* @retval 0 handler_event complete
* @brief 요청된 read를 수행한 후에 호출되는 signal_handler
* ====> signal_handler에서 signal을 감지했을 때완료된 요청이 있는지 검사
*/
int
handle_event (void)
{
int sig_return = 0, error_status = 0;
int ret_aio, ret_val;
size_t aiocb_index = 0, transfer_count = 0, count = 1, idx;;
posix_asynch_result* asynch_result;
///To get back the signal info.
siginfo_t sig_info;
struct timespec timeout; //set to "INFINITE"
#ifdef PROACTOR_DEBUG
printf("handle_event called\n");
#endif
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
sig_return = sigtimedwait(&RT_completion_signal, &sig_info, &timeout);
///Error case.
if (sig_return== -1 && errno == EAGAIN)
return -1;
if (sig_return == -1){
fprintf(stderr, "[Error] Error waiting for RT completion signals\n");
return -1;
}
if(sig_return != SIGRTMIN){
fprintf(stderr, "[Error] Unexpected Signal\n");
return -1;
}
// @@ Debugging.
//fprintf (stderr, "[Info] Sig number found in the sig_info block[RTSIG] : %d\n", sig_info.si_signo);
// @@ Debugging.
//fprintf (stderr, "[Info] Signal code for this signal delivery : %d\n", sig_info.si_code);
// Is the signal code an aio completion one?
if(sig_info.si_code == SI_ASYNCIO){
aiocb_index = (size_t)sig_info.si_value.sival_int;
#ifdef PROACTOR_DEBUG
fprintf(stderr, "[Info] aiocb_index : %d\n", aiocb_index);
#endif
}
else if(sig_info.si_code == SI_QUEUE){
assert(sig_info.si_code == SI_QUEUE);
fprintf(stderr, "[Info] sigqueue caught... good\n");
}
else //(sig_info.si_code != SI_ASYNCIO) && (sig_info.si_code != SI_QUEUE))
fprintf(stderr, "[Error] Unexpected signal code (%d) returned on completion querying\n", sig_info.si_code);
for(idx = 1; idx<aiocb_list_max_size; idx++){
ret_val = get_result_status(aiocb_list[idx], &error_status, &transfer_count);
if( ret_val == 1){ // "1" ; AIO Complete
// Call the application code.
application_specific_code (idx, transfer_count, error_status);
}
}//for
#ifdef PROACTOR_DEBUG
printf("handle_event end\n");
#endif
return 0;
}
/*
posix_asynch_result *
find_completed_aio(int *error_status, size_t *transfer_count, size_t index, size_t count)
{
size_t idx;
#ifdef PROACTOR_DEBUG
printf(" %d\t%d\t%d\t%d\n", *error_status, *transfer_count, index, count);
#endif
#if 0
posix_asynch_result* asynch_result = 0;
for (; count > 0; index++ , count--){
if (index >= aiocb_list_max_size) // like a wheel
index = 0;
if (aiocb_list[index] == 0) // Dont process null blocks.
continue;
#ifdef PROACTOR_DEBUG
printf(" %p\t%d\t%d\n", aiocb_list[index], *error_status, *transfer_count);
#endif
if(get_result_status(aiocb_list[index], error_status, transfer_count) != 0)
break;
}
if (count == 0) // all processed , nothing found
return 0;
asynch_result->aiocb = aiocb_list[index];
aiocb_list[index] = 0;
aiocb_list_cur_size--;
num_started_aio--; // decrement count active aios
index++; // for next iteration
count--; // for next iteration
// start_deferred_aio();
#else //0
posix_asynch_result* asynch_result = 0;
for(idx = count; idx<aiocb_list_max_size; idx++){
if (index >= aiocb_list_max_size) // like a wheel
index = 0;
if (aiocb_list[idx] == 0) // Dont process null blocks.
continue;
#ifdef PROACTOR_DEBUG
printf(" %p\t%d\t%d\n", aiocb_list[idx], *error_status, *transfer_count);
#endif
if(get_result_status(aiocb_list[idx], error_status, transfer_count) != 0)
continue;
}
#if 0
if (count == 0) // all processed , nothing found
return 0;
asynch_result->aiocb = aiocb_list[idx];
aiocb_list[idx] = 0;
aiocb_list_cur_size--;
num_started_aio--; // decrement count active aios
idx++; // for next iteration
count--; // for next iteration
#endif
#endif
return asynch_result;
}
*/
/**
* @author 박학선
* @param aiocb
* @param error_status
* @param transfer_count
* @retval 1 AIO completed
* @retval 0 not completed yet
* @brief AIO가 completed되었는지를 체크
*/
int
get_result_status (struct aiocb *aiocb, int *error_status, size_t *transfer_count)
{
ssize_t op_return;
transfer_count = 0;
#ifdef PROACTOR_DEBUG
printf("get_result_status\n");
#endif
// Get the error status of the aio_ operation.
*error_status = aio_error (aiocb);
if (*error_status == EINPROGRESS)
return 0; // not completed
op_return = aio_return (aiocb);
if (op_return > 0){
transfer_count = (size_t *) op_return;
// Successful.
#ifdef PROACTOR_DEBUG
fprintf(stderr,"nbytes : %d\n", op_return);
write(STDERR_FILENO, (char *)aiocb->aio_buf, op_return);
printf("\n");
#endif
}
return 1; // completed
}
/**
* @author 박학선
* @param idx
* @param transfer_count
* @param error_status
* @brief completed된 aiocb_list의 callback handler를 호출
*/
void
application_specific_code(size_t idx, int transfer_count, int error_status)
{
void *handler, *data;
#ifdef PROACTOR_DEBUG
printf("application_specific_code\n");
#endif
/// media interface에서 aio_read request를 던진 caller의 handler function으로 callback
result_list[idx]->hndlr(result_list[idx]->data);
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////REQEUEST////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/**
* @author 박학선
* @param file_fd
* @param size
* @param offset
* @param buf
* @param data
* @param hndlr_ftn
* @param priority
* @param op
* @brief media에서 asynchronous read를 요청하기 위해 호출하는 함수.
* 실제로는 이 파일안에 정의되어 있지는 않음. 단지 테스트를 위해서...
*/
int
si_read_req(int file_fd, int size, int offset, void *buf, void *data, void *hndlr_ftn, int priority, Opcode op)
{
posix_asynch_result *result;
struct aiocb * aiocb;
int ret_val;
aiocb = (struct aiocb*)malloc(sizeof(struct aiocb));
aiocb->aio_fildes = file_fd;
aiocb->aio_offset = offset;
aiocb->aio_nbytes = size;
aiocb->aio_buf = buf;
aiocb->aio_reqprio = priority;
result = (struct posix_asynch_result*)malloc(sizeof(struct posix_asynch_result));
result->aiocb = aiocb;
result->hndlr = hndlr_ftn;
result->data = data;
ret_val = issue_aio_calls(result, op);
if(ret_val == -1)
free(result);
return ret_val;
}
/**
* @author 박학선
* @param result
* @param op
* @retval 0 started OK
* @retval 1 OS AIO queue overflow
* @retval -1 do not started
* @brief System Interface(si_read_req())에서 Proactor에
* read를 요청하기 위해 사용!!
*/
int
issue_aio_calls (posix_asynch_result *result, Opcode op)
{
struct aiocb * aiocb;
int ret_val;
printf("issue_aio_calls\n");
aiocb = result->aiocb;
ret_val = (aiocb_list_cur_size >= aiocb_list_max_size) ? -1 : 0;
if (ret_val != 0){ // No free slot
errno = EAGAIN;
return -1;
}
if (aiocb == 0) // Just check the status of the list
return ret_val;
// Save operation code in the aiocb
switch (op){
case READ:
aiocb->aio_lio_opcode = LIO_READ;
break;
case WRITE:
aiocb->aio_lio_opcode = LIO_WRITE;
break;
default:
fprintf(stderr, "start_aio: Invalid operation code\n");
}
// Find a free slot and store.
ssize_t slot = allocate_aio_slot (aiocb);
if (slot < 0)
return -1;
size_t index = (size_t) slot;
// setup OS notification methods for this aio
// store index!!, not pointer in signal info
aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
aiocb->aio_sigevent.sigev_signo = SIGRTMIN; //Proactor에서 사용하는 signal
aiocb->aio_sigevent.sigev_value.sival_int = (int)index; //시그널이 발생했을 때 사용할 index
result_list[index]= result; //Store result ptr anyway
aiocb_list_cur_size++;
ret_val = execute_aio_calls (aiocb);
#ifdef PROACTOR_DEBUG
printf("ret_val from execute_aio_calls : %d\n", ret_val);
#endif
switch (ret_val){
case 0: // started OK
aiocb_list[index] = aiocb; //요청을 처리한 aiocb를 aiocb_list에 저장해 놓았다가 signal_handler에서 처리
return 0;
case 1: // OS AIO queue overflow
num_deferred_aiocb ++;
return 0;
default: // Invalid request, there is no point
break; // to start it later
}
result_list[index] = 0;
aiocb_list_cur_size--;
return -1;
}
/**
* @author 박학선
* @param aiocb
* @retval 0 AIO was started successfully
* @retval 1 AIO was not started, OS AIO queue overflow
* @retval -1 AIO was not started, other errors
* @brief 파일의 미디어 트랙에서 aio_read, aio_write를 실행!!
*/
int
execute_aio_calls (struct aiocb * aiocb)
{
int ret_val;
// Start IO
switch (aiocb->aio_lio_opcode ){
case LIO_READ :
ret_val = aio_read (aiocb);
break;
case LIO_WRITE :
ret_val = aio_write (aiocb);
break;
default:
ret_val = -1;
break;
}
if (ret_val == 0){
printf("aio_call excuted..\n");
num_started_aio++;
}
else{ // if (ret_val == -1)
if (errno == EAGAIN || errno == ENOMEM) //Ok, it will be deferred AIO
ret_val = 1;
}
return ret_val;
}
/**
* @author 박학선
* @param aiocb
* @retval retval > 0 allocated aiocb_list's slot
* @retval -1 no free slot
* @brief 이 시스템에서 관리하는 aiocb_list의 free slot을 반환한다.
*/
ssize_t allocate_aio_slot(struct aiocb * aiocb)
{
size_t i = 0;
//try to find free slot as usual, starting from 0
for (i = 1; i < aiocb_list_max_size; i++)
if (aiocb_list[i] == 0)
break;
#ifdef PROACTOR_DEBUG
printf("aiocblist_free_index found : %d\n", i);
#endif
if (i >= aiocb_list_max_size){
fprintf(stderr, "allocate_aio_slot internal error\n");
return -1;
}
return (ssize_t) i;
}
++++++++++++++++++++++++++
+ Makefile
++++++++++++++++++++++++++
.SUFFIXES: .c .o
CC= gcc
CFLAGS= -Wall -c -g
AR= ar
export CC AR CFLAGS
OBJS= posix_proactor.o
SUBDIR= test
TARGET= libsys_i.a
all: $(TARGET)
$(TARGET): $(OBJS)
$(AR) -r $(TARGET) $(OBJS)
clean:
$(RM) -rf *.o *.a
new:
$(MAKE) clean
$(MAKE)
subdirs:
@for i in $(SUBDIR); do (cd $$i && $(MAKE)); done
.c.o:
$(CC) $(CFLAGS) $<
ctags:
ctags -R .
'[Develope] > Network' 카테고리의 다른 글
TCP State Diagram (0) | 2008.07.28 |
---|---|
posix proactor library test (0) | 2008.07.01 |
netstat (0) | 2008.03.17 |
Aptana (0) | 2008.02.21 |
Protocol-Map (0) | 2008.01.24 |