Transcript QNX

QNX
Администратор ресурса
Resource manager
Required includes
•
•
•
•
•
•
•
•
#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#define THREAD_POOL_PARAM_T dispatch_context_t
#include <sys/iofunc.h>
#include <sys/dispatch.h>
Variables
• static resmgr_connect_funcs_t connect_funcs;
• static resmgr_io_funcs_t io_funcs;
• static iofunc_attr_t attr;
• int main(int argc, char **argv) {
–
–
–
–
–
–
thread_pool_attr_t pool_attr;
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
thread_pool_t *tpp;
dispatch_context_t *ctp;
int id;
initialize dispatch interface
• if((dpp = dispatch_create()) == NULL) {
– fprintf(stderr, "%s: Unable initialize dispatch interface\n", argv[0]);
– return EXIT_FAILURE;
}
initialize resource manager attributes
• memset(&resmgr_attr, 0, sizeof resmgr_attr);
• resmgr_attr.nparts_max = 1;
• resmgr_attr.msg_max_size = 2048;
initialize functions for handling
messages
• iofunc_func_init(
_RESMGR_CONNECT_NFUNCS,
&connect_funcs,
_RESMGR_IO_NFUNCS,
&io_funcs);
initialize attribute structure used by
the device
• iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
attach our device name
• id = resmgr_attach( dpp, /* dispatch handle */
&resmgr_attr,
/* resource manager attrs */
"/dev/sample", /* device name */
_FTYPE_ANY,
0,
&connect_funcs,
&io_funcs,
&attr);
/* open type */
/* flags */
/* connect routines */
/* I/O routines */
/* handle */
• if(id == -1) { return EXIT_FAILURE; }
initialize thread pool attributes
•
•
•
•
•
•
•
•
•
•
•
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.unblock_func = dispatch_unblock;
pool_attr.handler_func = dispatch_handler;
pool_attr.context_free = dispatch_context_free;
pool_attr.lo_water = 2;
pool_attr.hi_water = 4;
pool_attr.increment = 1;
pool_attr.maximum = 50;
allocate a thread pool handle
• if((tpp = thread_pool_create(
– &pool_attr,
– POOL_FLAG_EXIT_SELF)) == NULL) {
• fprintf(stderr, "%s: Unable to initialize thread pool.\n",
argv[0]);
• return EXIT_FAILURE;
• }
start the threads
• thread_pool_start(tpp);
• } // End of Main
io_funcs Substitution
•
•
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs, _RESMGR_IO_NFUNCS, &io_funcs);
• io_funcs.read = My_read;
• io_funcs.write = My_write;
• io_funcs.open = My_open;
My_read
•
•
•
•
•
•
•
•
•
int My_read( resmgr_context_t* ctp, io_read_t* msg, RESMGR_OCB_T* ocb )
{
int status; int xtype;
if ( ( status = iofunc_read_verify( ctp, msg, ocb, NULL ) ) != EOK ) {
return( status );
}
xtype = msg -> i.xtype & _IO_XTYPE_MASK ;
if (xtype == _IO_XTYPE_OFFSET) {
off = ((struct _xtype_offset *) (&msg->i+1))->offset;
} else if (xtype == _IO_XTYPE_NONE ) {
off = ocb->offset;
} else {
return( ENOSYS );
}
Return data
•
•
•
•
•
nparts = 2;
SETIOV( &ctp -> iov[ 0 ], datap1, length1 );
SETIOV( &ctp -> iov[ 1 ], datap2, length2 );
_IO_SET_READ_NBYTES( ctp, length1+length2);
if (xtype == _IO_XTYPE_NONE ) {
ocb->offset += length1+length2 ;
• }
• return( _RESMGR_NPARTS( nparts ) );
• } // My_read
My_write
• int buffer_write( resmgr_context_t* ctp, io_write_t* msg,
RESMGR_OCB_T* ocb ) {
• int status; int nbytes;
•
•
•
if ( ( status = iofunc_write_verify( ctp, msg, ocb, NULL ) ) != EOK ) {
return( status );
}
•
•
•
if ( ( msg -> i.xtype & _IO_XTYPE_MASK ) != _IO_XTYPE_NONE ) {
return( ENOSYS );
}
Getting data
• resmgr_msgread( ctp, buffer, nbytes, sizeof(
msg -> i) );
• _IO_SET_WRITE_NBYTES( ctp, nbytes );
• ocb -> attr -> flags |= IOFUNC_ATTR_MTIME |
IOFUNC_ATTR_CTIME;
• return( _RESMGR_NPARTS( 0 ) );
• } // End of My_write
Waiting
• iofunc_attr_unlock( ocb -> attr );
• < wait for something>
• iofunc_attr_lock( ocb -> attr );
My_open
• typedef struct{
•
iofunc_ocb_t ocb;
•
unsigned
key;
• } My_ocb_t;
• int My_open(resmgr_context_t *ctp, io_open_t *msg, void
*extra, void *reserved)
• {
• My_ocb_t * ocb = calloc(1, sizeof(*ocb));
• iofunc_open(ctp, msg, attr, NULL, &ci);
• return iofunc_ocb_attach(ctp, msg, &ocb->ocb, attr,
&io_funcs);
• }