QNX之编写资源管理器(六)

QNX相关历史文章:

  • QNX简介
  • QNX Neutrino微内核
  • QNX IPC机制
  • QNX进程管理器
  • QNX资源管理器
  • QNX字符I/O
  • QNX之编写资源管理器(一)
  • QNX之编写资源管理器(二)
  • QNX之编写资源管理器(三)
  • QNX之编写资源管理器(四)
  • QNX之编写资源管理器(五)

Extending the POSIX-Layer Data Structures

这篇文章主要描述如何扩展POSIX-Layer的数据结构。

1. Overview

如果使用默认的数据结构,不能满足需求时,可以对它进行扩展,需要把默认的结构包含在一个另外一个结构中,并且默认的成员放置在新定义结构的开始部分:


QNX之编写资源管理器(六)_第1张图片
Encapsulating the POSIX-layer data structures

2. Extending the OCB and attribute structures

在实际的使用过程中,我们可能需要扩展iofunc_attr_tiofunc_ocb_t结构,直接来看一个例子:

/* Define our overrides before including   */
struct device;
#define IOFUNC_ATTR_T       struct device  /* see note 1 */
struct ocb;
#define IOFUNC_OCB_T        struct ocb     /* see note 1 */

#include 
#include 

struct ocb {                               /* see note 2 */
    iofunc_ocb_t            hdr;           /* see note 4; must always be first */
    struct ocb              *next;
    struct ocb              **prev;        /* see note 3 */
};

struct device {                            /* see note 2 */
    iofunc_attr_t           attr;          /* must always be first */
    struct ocb              *list;         /* waiting for write */
};

/* Prototypes, needed since we refer to them a few lines down */

struct ocb *ocb_calloc (resmgr_context_t *ctp, struct device *device);
void ocb_free (struct ocb *ocb);

iofunc_funcs_t ocb_funcs = { /* our ocb allocating & freeing functions */
    _IOFUNC_NFUNCS,
    ocb_calloc,
    ocb_free
};

/* The mount structure.  We have only one, so we statically declare it */

iofunc_mount_t          mountpoint = { 0, 0, 0, 0, &ocb_funcs };

/* One struct device per attached name (there's only one name in this
   example) */

struct device           deviceattr;

main()
{
    ...

    /* 
     *  deviceattr will indirectly contain the addresses 
     *  of the OCB allocating and freeing functions
     */

    deviceattr.attr.mount = &mountpoint;
    resmgr_attach (..., &deviceattr);

    ...
}

/*
 * ocb_calloc
 *
 *  The purpose of this is to give us a place to allocate our own OCB.
 *  It is called as a result of the open being done
 *  (e.g. iofunc_open_default causes it to be called). We
 *  registered it through the mount structure.
 */
IOFUNC_OCB_T
ocb_calloc (resmgr_context_t *ctp, IOFUNC_ATTR_T *device)
{
    struct ocb *ocb;

    if (!(ocb = calloc (1, sizeof (*ocb)))) {
        return 0;
    }

    /* see note 3 */
    ocb -> prev = &device -> list;
    if (ocb -> next = device -> list) {
        device -> list -> prev = &ocb -> next;
    }
    device -> list = ocb;
    
    return (ocb);
}

/*
 * ocb_free
 *
 * The purpose of this is to give us a place to free our OCB.
 * It is called as a result of the close being done
 * (e.g. iofunc_close_ocb_default causes it to be called). We
 * registered it through the mount structure.
 */
void
ocb_free (IOFUNC_OCB_T *ocb)
{
    /* see note 3 */
    if (*ocb -> prev = ocb -> next) {
        ocb -> next -> prev = ocb -> prev;
        }
        free (ocb);
}
  • note 1
    在包含标准I/O函数头文件之前,放置了结构的定义,这样在I/O函数中使用到这些宏定义的时候,可以方便的进行结构的覆盖;
  • note 2
    定义新的数据结构,确保原有的放置在头部;
  • note 3
    ocb_calloc()ocb_free()示例函数,将新创建的ocb维护在一个列表中;
  • note 4
    必须始终把将iofunc结构作为新扩展结构的第一个成员,这能确保公共库在默认情况下能正常工作;

3. Extending the mount structure

iofunc_mount_t的扩展方式,与上述结构是一样的,比如:

#define IOFUNC_MOUNT_T       struct newmount 

/* then add statements */
struct newmount {
    iofunc_mount_t          mount;
    int                   ourflag;
};

你可能感兴趣的:(QNX之编写资源管理器(六))