// "пустую" операцию и не блокировать атрибутную запись,
// чем обеспечиваем параллелизм.
static int nolock(resmgr_context_t *ctp, void *v, IOFUNC_OCB_T *ocb) {
return EOK;
}
// обработчик запроса чтения
static int line_read(resmgr_context_t *ctp, io_read_t *msg,
IOFUNC_OCB_T *ocb) {
if (strlen(ocb->buf) != 0) {
MsgReply(ctp->rcvid, strlen(ocb->buf) + 1, ocb->buf, strlen(ocb->buf) + 1);
strcpy(ocb->buf, "");
} else MsgReply(ctp->rcvid, EOK, NULL, 0);
return _RESMGR_NOREPLY;
}
// обработчик запроса записи
static int line_write(resmgr_context_t *ctp, io_write_t *msg,
IOFUNC_OCB_T *ocb) {
resmgr_msgread(ctp, ocb->buf, msg->i.nbytes, sizeof(msg->i));
_IO_SET_WRITE_NBYTES(ctp, msg->i.nbytes);
return EOK;
}
// имя, под которым регистрируется менеджер:
const char sResName[_POSIX_PATH_MAX + 1] = "/dev/wmng";
// старт менеджера ресурса
static void StartResMng(void) {
dispatch_t* dpp;
if ((dpp = dispatch_create) == NULL)
perror("dispatch create"), exit(EXIT_FAILURE);
resmgr_attr_t resmgr_attr;
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;
// статичность 3-х последующих описаний принципиально важна!
// (также они могут быть сделаны глобальными переменными файла):
static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
// переопределение обработчиков по умолчанию
io_funcs.read = line_read;
io_funcs.write = line_write;
io_funcs.lock_ocb = nolock;
iofunc_attr_init(&attr, S_IFNAM | 0666, NULL, NULL);
// через это поле осуществляется связь с новой
// структурой OCB.
attr.mount = &mountpoint
if (resmgr_attach(dpp, &resmgr_attr, sResName, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs, &attr) == -1)
perror("name attach"), exit(EXIT_FAILURE);
// создание пула потоков (многопоточность)
thread_pool_attr_t pool_attr;
memset(&pool_attr, 0, sizeof pool_attr);
pool_attr.handle = dpp;
pool_attr.context_alloc = dispatch_context_alloc;
pool_attr.block_func = dispatch_block;
pool_attr.handler_func = dispatch_handler;
pool_attr.context_free = dispatch_context_free;
pool_attr.lo_water = 2;
pool_attr.hi_water = 6;
pool_attr.increment = 1;
pool_attr.maximum = 50;
thread_pool_t* tpp;
if ((tpp = thread_pool_create(&pool_attr, POOL_FLAG_EXIT_SELF)) == NULL)
perror("pool create"), exit(EXIT_FAILURE);
thread_pool_start(tpp);
// к этой точке return управление уже никогда не подойдет...
}
int main(int argc, char *argv[]) {