Литмир - Электронная Библиотека
Содержание  
A
A

<b>static int nolock(resmgr_context_t *ctp, void *v, IOFUNC_OCB_T *ocb) {</b>

<b> return EOK;</b>

<b>}</b>

// обработчик запроса чтения

static int line_read(resmgr_context_t *ctp, io_read_t *msg,

 IOFUNC_OCB_T *ocb) {

 if (strlen(ocb-&gt;buf) != 0) {

  MsgReply(ctp-&gt;rcvid, strlen(ocb-&gt;buf) + 1, ocb-&gt;buf, strlen(ocb-&gt;buf) + 1);

  strcpy(ocb-&gt;buf, &quot;&quot;);

 } else MsgReply(ctp-&gt;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-&gt;buf, msg-&gt;i.nbytes, sizeof(msg-&gt;i));

 _IO_SET_WRITE_NBYTES(ctp, msg-&gt;i.nbytes);

 return EOK;

}

// имя, под которым регистрируется менеджер:

const char sResName[_POSIX_PATH_MAX + 1] = &quot;/dev/wmng&quot;;

// старт менеджера ресурса

static void StartResMng(void) {

 dispatch_t* dpp;

 if ((dpp = dispatch_create()) == NULL)

  perror(&quot;dispatch create&quot;), exit(EXIT_FAILURE);

 resmgr_attr_t resmgr_attr;

 memset(&amp;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, &amp;connect_funcs,

  _RESMGR_IO_NFUNCS, &amp;io_funcs);

 // переопределение обработчиков по умолчанию

 io_funcs.read = line_read;

 io_funcs.write = line_write;

<b> io_funcs.lock_ocb = nolock;</b>

 iofunc_attr_init(&amp;attr, S_IFNAM | 0666, NULL, NULL);

 // через это поле осуществляется связь с новой

 // структурой OCB.

<b> attr.mount = &amp;mountpoint;</b>

 if (resmgr_attach(dpp, &amp;resmgr_attr, sResName, _FTYPE_ANY, 0,

  &amp;connect_funcs, &amp;io_funcs, &amp;attr) == -1)

  perror(&quot;name attach&quot;), exit(EXIT_FAILURE);

 // создание пула потоков (многопоточность)

 thread_pool_attr_t pool_attr;

 memset(&amp;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(&amp;pool_attr, POOL_FLAG_EXIT_SELF)) == NULL)

  perror(&quot;pool create&quot;), exit(EXIT_FAILURE);

 thread_pool_start(tpp);

 // к этой точке return управление уже никогда не подойдет...

}

int main(int argc, char *argv[]) {

 // проверка, не загружен ли ранее экземпляр менеджера,

 // 2 экземпляра нам ни к чему...

 char sDirName[_POSIX_NAME_MAX + 1];

 int nDirLen = strrchr((const char*)sResName, '/') - (char*)sResName;

 strncpy(sDirName, sResName, nDirLen);

 sDirName[nDirLen] = '\0';

 DIR *dirp = opendir(sDirName);

 if (dirp == NULL)

  perror(&quot;directory not found&quot;), exit(EXIT_FAILURE);

 struct dirent *direntp;

 while (true) {

  if ((direntp = readdir(dirp)) == NULL) break;

  if (strcmp(direntp-&gt;d_name, strrchr(sResName, '/') + 1) == 0)

   cout &lt;&lt; &quot;second copy of manager&quot; &lt;&lt; endl, exit(EXIT_FAILURE);

 }

 closedir(dirp);

 // старт менеджера

 StartResMng();

 // ... к этой точке мы уже никогда не подойдем...

 exit(EXIT_SUCCESS);

87
{"b":"155449","o":1}