ssize_t ipc_shmem_query (ipc_t *ipc, request_t *request){ // {{{ ssize_t ret; uintmax_t f_async = 0; data_t *buffer; ipc_shmem_block *block; ipc_shmem_userdata *userdata = (ipc_shmem_userdata *)ipc->userdata; // check async state switch(userdata->forced_state){ case FORCE_SYNC: break; // already == 0 case FORCE_ASYNC: f_async = 1; break; case FORCE_NONE: hash_data_get(ret, TYPE_UINTT, f_async, request, HK(async)); break; }; buffer = hash_data_find(request, userdata->buffer); // send request if( (block = shmem_get_block(userdata, STATUS_FREE, STATUS_WRITING)) == NULL) return error("strange error"); // write data to ipc memory data_t d_ipcmem = DATA_RAW(userdata->shmdata + block->data_rel_ptr, userdata->shmaddr->item_size); fastcall_convert_to r_convert = { { 4, ACTION_CONVERT_TO }, &d_ipcmem, FORMAT(packed) }; if( (ret = data_query(buffer, &r_convert)) < 0) return error("can not write buffer to ipc memory"); //block->size = r_read.buffer_size; block->return_result = (f_async == 0) ? 1 : 0; if( (ret = shmem_block_status(userdata, block, STATUS_WRITING, STATUS_WRITTEN)) < 0) return ret; if(f_async == 0){ // synchronous request // wait for answer sem_wait(&block->sem_done); // read request back if(userdata->return_result != 0){ fastcall_convert_from r_convert_from = { { 5, ACTION_CONVERT_FROM }, &d_ipcmem, FORMAT(packed) }; data_query(buffer, &r_convert_from); } ret = 0; if(shmem_block_status(userdata, block, STATUS_EXEC_DONE, STATUS_FREE) < 0) return error("strange error 3"); }else{ ret = 0; // success } return ret; } // }}}
ssize_t action_io_to_hash(void *userdata, fastcall_io *fargs, f_fast_to_hash callback){ // {{{ ssize_t ret; request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(offset), DATA_UINTT( fargs->offset ) }, { HK(buffer), DATA_RAW( fargs->buffer, fargs->buffer_size ) }, { HK(size), DATA_UINTT( fargs->buffer_size ) }, hash_end }; ret = callback(userdata, r_next); fargs->offset = DEREF_TYPE_UINTT(&r_next[1].data); fargs->buffer_size = DEREF_TYPE_UINTT(&r_next[3].data); return ret; } // }}}
void * ipc_shmem_listen (void *ipc){ // {{{ ipc_shmem_block *block; ipc_shmem_userdata *userdata = (ipc_shmem_userdata *)((ipc_t *)ipc)->userdata; while(1){ if( (block = shmem_get_block(userdata, STATUS_WRITTEN, STATUS_EXECUTING)) == NULL) break; // run request request_t req[] = { { userdata->buffer, DATA_RAW( userdata->shmdata + block->data_rel_ptr, userdata->shmaddr->item_size ) }, hash_end }; machine_pass(((ipc_t *)ipc)->machine, req); // update status. if client don't want read results - free block, overwise notify client if(shmem_block_status(userdata, block, STATUS_EXECUTING, ((block->return_result == 0) ? STATUS_FREE : STATUS_EXEC_DONE) ) < 0) break; } //error("ipc_shmem_listen dead\n"); return NULL; } // }}}
request_t values[] = { { HK(key4), DATA_STRING("hello") }, { HK(key1), DATA_UINT32T(100) }, { HK(key2), DATA_OFFT(10) }, { HK(key3), DATA_UINT32T(0) }, hash_end }; ssize_t ret; char test[100] = {0}; char orig[] = "\x64\x00\x00\x00" "\x0A\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" "hello\x00"; data_t test_data = DATA_RAW(test, 100); ret = struct_pack(structure, values, &test_data); fail_unless(ret > 0, "struct_pack failed"); fail_unless(memcmp(test, orig, sizeof(orig)) == 0, "struct_pack data failed"); uint32_t test1; off_t test2; char *test3 = malloc(100); memset(test3, 0x41, 99); test3[99] = 0; request_t query[] = { { HK(key4), DATA_STRING(test3) }, { HK(key1), DATA_UINT32T(0) }, { HK(key2), DATA_OFFT(0) },