# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file

"""
Device module introduces the Context and DeviceAttr class.
It allows user to open an IB device (using Context(name=<name>) and query it,
which returns a DeviceAttr object.
"""
import weakref

from .pyverbs_error import PyverbsRDMAError, PyverbsError
from pyverbs.cq cimport CQEX, CQ, CompChannel
from .pyverbs_error import PyverbsUserError
from pyverbs.base import PyverbsRDMAErrno
from pyverbs.base cimport close_weakrefs
from pyverbs.wq cimport WQ, RwqIndTable
cimport pyverbs.libibverbs_enums as e
cimport pyverbs.libibverbs as v
cimport pyverbs.librdmacm as cm
from pyverbs.cmid cimport CMID
from pyverbs.xrcd cimport XRCD
from pyverbs.addr cimport GID
from pyverbs.mr import DMMR
from pyverbs.pd cimport PD
from pyverbs.qp cimport QP
from libc.stdlib cimport free, malloc
from libc.string cimport memset
from libc.stdint cimport uint64_t
from libc.stdint cimport uint16_t
from libc.stdint cimport uint32_t
from pyverbs.utils import gid_str

cdef extern from 'endian.h':
    unsigned long be64toh(unsigned long host_64bits);


class Device(PyverbsObject):
    """
    Device class represents the C ibv_device. It stores device's properties.
    It is not a part of objects creation order - there's no need for the user
    to create it for such purposes.
    """
    def __init__(self, name, guid, node_type, transport_type, index):
        self._node_type = node_type
        self._transport_type = transport_type
        self._name = name
        self._guid = guid
        self._index = index

    @property
    def name(self):
        return self._name

    @property
    def node_type(self):
        return self._node_type

    @property
    def transport_type(self):
        return self._transport_type

    @property
    def guid(self):
        return self._guid

    @property
    def index(self):
        return self._index

    def __str__(self):
        return 'Device {dev}, node type {ntype}, transport type {ttype},' \
               ' guid {guid}, index {index}'.format(dev=self.name.decode(),
                ntype=translate_node_type(self.node_type),
                ttype=translate_transport_type(self.transport_type),
                guid=guid_to_hex(self.guid), index=self._index)


cdef class Context(PyverbsCM):
    """
    Context class represents the C ibv_context.
    """
    def __init__(self, **kwargs):
        """
        Initializes a Context object. The function searches the IB devices list
        for a device with the name provided by the user. If such a device is
        found, it is opened (unless provider attributes were given).
        In case of cmid argument, CMID object already holds an ibv_context
        initiated pointer, hence all we have to do is assign this pointer to
        Context's object pointer.
        :param kwargs: Arguments:
            * *name*
              The device's name
            * *attr*
              Provider-specific attributes. If not None, it means that the
              device will be opened by the provider and __init__ will return
              after locating the requested device.
            * *cmid*
              A CMID object. If not None, it means that the device was already
              opened by a CMID class, and only a pointer assignment is missing.
            * *cmd_fd*
              A command FD. If passed, the device will be imported from the
              given cmd_fd using ibv_import_device.
        :return: None
        """
        cdef int count
        cdef v.ibv_device **dev_list
        cdef CMID cmid

        super().__init__()
        self.pds = weakref.WeakSet()
        self.dms = weakref.WeakSet()
        self.ccs = weakref.WeakSet()
        self.cqs = weakref.WeakSet()
        self.qps = weakref.WeakSet()
        self.xrcds = weakref.WeakSet()
        self.vars = weakref.WeakSet()
        self.uars = weakref.WeakSet()
        self.pps = weakref.WeakSet()
        self.sched_nodes = weakref.WeakSet()
        self.sched_leafs = weakref.WeakSet()
        self.dr_domains = weakref.WeakSet()
        self.wqs = weakref.WeakSet()
        self.rwq_ind_tbls = weakref.WeakSet()
        self.crypto_logins = weakref.WeakSet()

        self.name = kwargs.get('name')
        provider_attr = kwargs.get('attr')
        cmid = kwargs.get('cmid')
        cmd_fd = kwargs.get('cmd_fd')
        if cmid is not None:
            self.context = cmid.id.verbs
            self.name = str(v.ibv_get_device_name(self.context.device).decode('utf-8'))
            cmid.ctx = self
            return
        if cmd_fd is not None:
            self.context = v.ibv_import_device(cmd_fd)
            if self.context == NULL:
                raise PyverbsRDMAErrno('Failed to import device')
            self.name = str(v.ibv_get_device_name(self.context.device).decode('utf-8'))
            return

        if self.name is None:
            raise PyverbsUserError('Device name must be provided')
        dev_list = v.ibv_get_device_list(&count)
        if dev_list == NULL:
            raise PyverbsRDMAError('Failed to get devices list')
        try:
            for i in range(count):
                if dev_list[i].name.decode() == self.name:
                    if provider_attr is not None:
                        # A provider opens its own context, we're just
                        # setting its IB device
                        self.device = dev_list[i]
                        return
                    self.context = v.ibv_open_device(dev_list[i])
                    if self.context == NULL:
                        raise PyverbsRDMAErrno('Failed to open device {dev}'.
                                               format(dev=self.name))
                    self.logger.debug('Context: opened device {dev}'.
                                      format(dev=self.name))
                    break
            else:
                raise PyverbsRDMAError('Failed to find device {dev}'.
                                       format(dev=self.name))
        finally:
            v.ibv_free_device_list(dev_list)

    def __dealloc__(self):
        """
        Closes the inner IB device.
        :return: None
        """
        self.close()

    cpdef close(self):
        if self.context != NULL:
            if self.logger:
                self.logger.debug('Closing Context')
            close_weakrefs([self.qps, self.crypto_logins, self.rwq_ind_tbls, self.wqs, self.ccs, self.cqs,
                            self.dms, self.pds, self.xrcds, self.vars, self.sched_leafs,
                            self.sched_nodes, self.dr_domains])
            rc = v.ibv_close_device(self.context)
            if rc != 0:
                raise PyverbsRDMAErrno(f'Failed to close device {self.name}')
            self.context = NULL

    @property
    def context(self):
        return <object>self.context

    @property
    def num_comp_vectors(self):
        return self.context.num_comp_vectors

    def query_device(self):
        """
        Queries the device's attributes.
        :return: A DeviceAttr object which holds the device's attributes as
                 reported by the hardware.
        """
        dev_attr = DeviceAttr()
        rc = v.ibv_query_device(self.context, &dev_attr.dev_attr)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query device {name}'.
                                   format(name=self.name), rc)
        return dev_attr

    def query_device_ex(self, QueryDeviceExInput ex_input = None):
        """
        Queries the device's extended attributes.
        :param ex_input: An extensible input struct for possible future
                         extensions
        :return: DeviceAttrEx object
        """
        dev_attr_ex = DeviceAttrEx()
        rc = v.ibv_query_device_ex(self.context,
                                   &ex_input.input if ex_input is not None else NULL,
                                   &dev_attr_ex.dev_attr)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query EX device {name}'.
                                   format(name=self.name), rc)
        return dev_attr_ex

    def query_pkey(self, unsigned int port_num, int index):
        cdef uint16_t pkey
        rc = v.ibv_query_pkey(self.context, port_num, index, &pkey)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query pkey {index} of port {port_num}')
        return pkey

    def get_pkey_index(self, unsigned int port_num, int pkey):
        idx = v.ibv_get_pkey_index(self.context, port_num, pkey)
        if idx == -1:
            raise PyverbsRDMAError(f'Failed to get pkey index of pkey = {pkey} of port {port_num}')
        return idx

    def query_gid(self, unsigned int port_num, int index):
        gid = GID()
        rc = v.ibv_query_gid(self.context, port_num, index, &gid.gid)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query gid {idx} of port {port}'.
                                                                   format(idx=index, port=port_num))
        return gid

    def query_gid_type(self, unsigned int port_num, unsigned int index):
        cdef v.ibv_gid_type_sysfs gid_type
        rc = v.ibv_query_gid_type(self.context, port_num, index, &gid_type)
        if rc != 0:
            raise PyverbsRDMAErrno('Failed to query gid type of port {p} and gid index {g}'
                                   .format(p=port_num, g=index))
        return gid_type

    def query_port(self, unsigned int port_num):
        """
        Query port <port_num> of the device and returns its attributes.
        :param port_num: Port number to query
        :return: PortAttr object on success
        """
        port_attrs = PortAttr()
        rc = v.ibv_query_port(self.context, port_num, &port_attrs.attr)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query port {p}'.
                                   format(p=port_num), rc)
        return port_attrs

    def query_gid_table(self, size_t max_entries, uint32_t flags=0):
        """
        Queries the GID tables of the device for at most <max_entries> entries
        and returns them.
        :param max_entries: Maximum number of GID entries to retrieve
        :param flags: Specifies new extra members of struct ibv_gid_entry to
                      query
        :return: List of GIDEntry objects on success
        """
        cdef v.ibv_gid_entry *entries
        cdef v.ibv_gid_entry entry

        entries = <v.ibv_gid_entry *>malloc(max_entries *
                                            sizeof(v.ibv_gid_entry))
        rc = v.ibv_query_gid_table(self.context, entries, max_entries, flags)
        if rc < 0:
            raise PyverbsRDMAError('Failed to query gid tables of the device',
                                   rc)
        gid_entries = []
        for i in range(rc):
            entry = entries[i]
            gid_entries.append(GIDEntry(entry.gid._global.subnet_prefix,
                               entry.gid._global.interface_id, entry.gid_index,
                               entry.port_num, entry.gid_type,
                               entry.ndev_ifindex))
        free(entries)
        return gid_entries

    def query_gid_ex(self, uint32_t port_num, uint32_t gid_index,
                     uint32_t flags=0):
        """
        Queries the GID table of port <port_num> in index <gid_index>, and
        returns the GID entry.
        :param port_num: The port number to query
        :param gid_index: The index in the GID table to query
        :param flags: Specifies new extra members of struct ibv_gid_entry to
                      query
        :return: GIDEntry object on success
        """
        entry = GIDEntry()
        rc = v.ibv_query_gid_ex(self.context, port_num, gid_index,
                                &entry.entry, flags)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query gid table of port '\
                                   f'{port_num} in index {gid_index}', rc)
        return entry

    def query_rt_values_ex(self, comp_mask=v.IBV_VALUES_MASK_RAW_CLOCK):
        """
        Query an RDMA device for some real time values.
        :return: A tuple of the real time values according to comp_mask (sec, nsec)
        """
        cdef v.ibv_values_ex *val
        val = <v.ibv_values_ex *>malloc(sizeof(v.ibv_values_ex))
        val.comp_mask = comp_mask
        rc = v.ibv_query_rt_values_ex(self.context, val)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query real time values', rc)
        if val.comp_mask != comp_mask:
            raise PyverbsRDMAError(f'Failed to query real time values with requested comp_mask')
        nsec = (<v.ibv_values_ex *>val).raw_clock.tv_nsec
        sec = (<v.ibv_values_ex *>val).raw_clock.tv_sec
        free(val)
        return sec, nsec

    cdef add_ref(self, obj):
        if isinstance(obj, PD):
            self.pds.add(obj)
        elif isinstance(obj, DM):
            self.dms.add(obj)
        elif isinstance(obj, CompChannel):
            self.ccs.add(obj)
        elif isinstance(obj, CQ) or isinstance(obj, CQEX):
            self.cqs.add(obj)
        elif isinstance(obj, QP):
            self.qps.add(obj)
        elif isinstance(obj, XRCD):
            self.xrcds.add(obj)
        elif isinstance(obj, WQ):
            self.wqs.add(obj)
        elif isinstance(obj, RwqIndTable):
            self.rwq_ind_tbls.add(obj)
        else:
            raise PyverbsError('Unrecognized object type')

    def get_async_event(self):
        event = AsyncEvent()
        rc = v.ibv_get_async_event(self.context, &event.event)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to get async event', rc)
        return event

    @property
    def cmd_fd(self):
        return self.context.cmd_fd

    @property
    def name(self):
        return self.name


cdef class DeviceAttr(PyverbsObject):
    """
    DeviceAttr represents ibv_device_attr C class. It exposes the same
    properties (read only) and also provides an __str__() function for
    readability.
    """
    @property
    def fw_version(self):
        return self.dev_attr.fw_ver.decode()
    @property
    def node_guid(self):
        return self.dev_attr.node_guid
    @property
    def sys_image_guid(self):
        return self.dev_attr.sys_image_guid
    @property
    def max_mr_size(self):
        return self.dev_attr.max_mr_size
    @property
    def page_size_cap(self):
        return self.dev_attr.page_size_cap
    @property
    def vendor_id(self):
        return self.dev_attr.vendor_id
    @property
    def vendor_part_id(self):
        return self.dev_attr.vendor_part_id
    @property
    def hw_ver(self):
        return self.dev_attr.hw_ver
    @property
    def max_qp(self):
        return self.dev_attr.max_qp
    @property
    def max_qp_wr(self):
        return self.dev_attr.max_qp_wr
    @property
    def device_cap_flags(self):
        return self.dev_attr.device_cap_flags
    @property
    def max_sge(self):
        return self.dev_attr.max_sge
    @property
    def max_sge_rd(self):
        return self.dev_attr.max_sge_rd
    @property
    def max_cq(self):
        return self.dev_attr.max_cq
    @property
    def max_cqe(self):
        return self.dev_attr.max_cqe
    @property
    def max_mr(self):
        return self.dev_attr.max_mr
    @property
    def max_pd(self):
        return self.dev_attr.max_pd
    @property
    def max_qp_rd_atom(self):
        return self.dev_attr.max_qp_rd_atom
    @property
    def max_ee_rd_atom(self):
        return self.dev_attr.max_ee_rd_atom
    @property
    def max_res_rd_atom(self):
        return self.dev_attr.max_res_rd_atom
    @property
    def max_qp_init_rd_atom(self):
        return self.dev_attr.max_qp_init_rd_atom
    @property
    def max_ee_init_rd_atom(self):
        return self.dev_attr.max_ee_init_rd_atom
    @property
    def atomic_caps(self):
        return self.dev_attr.atomic_cap
    @property
    def max_ee(self):
        return self.dev_attr.max_ee
    @property
    def max_rdd(self):
        return self.dev_attr.max_rdd
    @property
    def max_mw(self):
        return self.dev_attr.max_mw
    @property
    def max_raw_ipv6_qps(self):
        return self.dev_attr.max_raw_ipv6_qp
    @property
    def max_raw_ethy_qp(self):
        return self.dev_attr.max_raw_ethy_qp
    @property
    def max_mcast_grp(self):
        return self.dev_attr.max_mcast_grp
    @property
    def max_mcast_qp_attach(self):
        return self.dev_attr.max_mcast_qp_attach
    @property
    def max_ah(self):
        return self.dev_attr.max_ah
    @property
    def max_fmr(self):
        return self.dev_attr.max_fmr
    @property
    def max_map_per_fmr(self):
        return self.dev_attr.max_map_per_fmr
    @property
    def max_srq(self):
        return self.dev_attr.max_srq
    @property
    def max_srq_wr(self):
        return self.dev_attr.max_srq_wr
    @property
    def max_srq_sge(self):
        return self.dev_attr.max_srq_sge
    @property
    def max_pkeys(self):
        return self.dev_attr.max_pkeys
    @property
    def local_ca_ack_delay(self):
        return self.dev_attr.local_ca_ack_delay
    @property
    def phys_port_cnt(self):
        return self.dev_attr.phys_port_cnt

    def __str__(self):
        print_format = '{:<22}: {:<20}\n'
        return print_format.format('FW version', self.fw_version) +\
            print_format.format('Node guid', guid_format(self.node_guid)) +\
            print_format.format('Sys image GUID', guid_format(self.sys_image_guid)) +\
            print_format.format('Max MR size', hex(self.max_mr_size).replace('L', '')) +\
            print_format.format('Page size cap', hex(self.page_size_cap).replace('L', '')) +\
            print_format.format('Vendor ID', hex(self.vendor_id)) +\
            print_format.format('Vendor part ID', self.vendor_part_id) +\
            print_format.format('HW version', self.hw_ver) +\
            print_format.format('Max QP', self.max_qp) +\
            print_format.format('Max QP WR', self.max_qp_wr) +\
            print_format.format('Device cap flags',
                                translate_device_caps(self.device_cap_flags)) +\
            print_format.format('Max SGE', self.max_sge) +\
            print_format.format('Max SGE RD', self.max_sge_rd) +\
            print_format.format('MAX CQ', self.max_cq) +\
            print_format.format('Max CQE', self.max_cqe) +\
            print_format.format('Max MR', self.max_mr) +\
            print_format.format('Max PD', self.max_pd) +\
            print_format.format('Max QP RD atom', self.max_qp_rd_atom) +\
            print_format.format('Max EE RD atom', self.max_ee_rd_atom) +\
            print_format.format('Max res RD atom', self.max_res_rd_atom) +\
            print_format.format('Max QP init RD atom', self.max_qp_init_rd_atom) +\
            print_format.format('Max EE init RD atom', self.max_ee_init_rd_atom) +\
            print_format.format('Atomic caps', self.atomic_caps) +\
            print_format.format('Max EE', self.max_ee) +\
            print_format.format('Max RDD', self.max_rdd) +\
            print_format.format('Max MW', self.max_mw) +\
            print_format.format('Max raw IPv6 QPs', self.max_raw_ipv6_qps) +\
            print_format.format('Max raw ethy QP', self.max_raw_ethy_qp) +\
            print_format.format('Max mcast group', self.max_mcast_grp) +\
            print_format.format('Max mcast QP attach', self.max_mcast_qp_attach) +\
            print_format.format('Max AH', self.max_ah) +\
            print_format.format('Max FMR', self.max_fmr) +\
            print_format.format('Max map per FMR', self.max_map_per_fmr) +\
            print_format.format('Max SRQ', self.max_srq) +\
            print_format.format('Max SRQ WR', self.max_srq_wr) +\
            print_format.format('Max SRQ SGE', self.max_srq_sge) +\
            print_format.format('Max PKeys', self.max_pkeys) +\
            print_format.format('local CA ack delay', self.local_ca_ack_delay) +\
            print_format.format('Phys port count', self.phys_port_cnt)


cdef class QueryDeviceExInput(PyverbsObject):
    def __init__(self, comp_mask):
        super().__init__()
        self.ex_input.comp_mask = comp_mask


cdef class ODPCaps(PyverbsObject):
    @property
    def general_caps(self):
        return self.odp_caps.general_caps
    @property
    def rc_odp_caps(self):
        return self.odp_caps.per_transport_caps.rc_odp_caps
    @property
    def uc_odp_caps(self):
        return self.odp_caps.per_transport_caps.uc_odp_caps
    @property
    def ud_odp_caps(self):
        return self.odp_caps.per_transport_caps.ud_odp_caps
    @property
    def xrc_odp_caps(self):
        return self.xrc_odp_caps
    @xrc_odp_caps.setter
    def xrc_odp_caps(self, val):
       self.xrc_odp_caps = val

    def __str__(self):
        general_caps = {e.IBV_ODP_SUPPORT: 'IBV_ODP_SUPPORT',
              e.IBV_ODP_SUPPORT_IMPLICIT: 'IBV_ODP_SUPPORT_IMPLICIT'}

        l = {e.IBV_ODP_SUPPORT_SEND: 'IBV_ODP_SUPPORT_SEND',
             e.IBV_ODP_SUPPORT_RECV: 'IBV_ODP_SUPPORT_RECV',
             e.IBV_ODP_SUPPORT_WRITE: 'IBV_ODP_SUPPORT_WRITE',
             e.IBV_ODP_SUPPORT_READ: 'IBV_ODP_SUPPORT_READ',
             e.IBV_ODP_SUPPORT_ATOMIC: 'IBV_ODP_SUPPORT_ATOMIC',
             e.IBV_ODP_SUPPORT_SRQ_RECV: 'IBV_ODP_SUPPORT_SRQ_RECV',
             e.IBV_ODP_SUPPORT_FLUSH: 'IBV_ODP_SUPPORT_FLUSH',
             e.IBV_ODP_SUPPORT_ATOMIC_WRITE: 'IBV_ODP_SUPPORT_ATOMIC_WRITE'}

        print_format = '{}: {}\n'
        return print_format.format('ODP General caps', str_from_flags(self.general_caps, general_caps)) +\
            print_format.format('RC ODP caps', str_from_flags(self.rc_odp_caps, l)) +\
            print_format.format('UD ODP caps', str_from_flags(self.ud_odp_caps, l)) +\
            print_format.format('UC ODP caps', str_from_flags(self.uc_odp_caps, l)) +\
            print_format.format('XRC ODP caps', str_from_flags(self.xrc_odp_caps, l))


cdef class PCIAtomicCaps(PyverbsObject):
    @property
    def fetch_add(self):
        return self.caps.fetch_add
    @property
    def swap(self):
        return self.caps.swap
    @property
    def compare_swap(self):
        return self.caps.compare_swap


cdef class TSOCaps(PyverbsObject):
    @property
    def max_tso(self):
        return self.tso_caps.max_tso
    @property
    def supported_qpts(self):
        return self.tso_caps.supported_qpts


cdef class RSSCaps(PyverbsObject):
    @property
    def supported_qpts(self):
        return self.rss_caps.supported_qpts
    @property
    def max_rwq_indirection_tables(self):
        return self.rss_caps.max_rwq_indirection_tables
    @property
    def rx_hash_fields_mask(self):
        return self.rss_caps.rx_hash_fields_mask
    @property
    def rx_hash_function(self):
        return self.rss_caps.rx_hash_function
    @property
    def max_rwq_indirection_table_size(self):
        return self.rss_caps.max_rwq_indirection_table_size


cdef class PacketPacingCaps(PyverbsObject):
    @property
    def qp_rate_limit_min(self):
        return self.packet_pacing_caps.qp_rate_limit_min
    @property
    def qp_rate_limit_max(self):
        return self.packet_pacing_caps.qp_rate_limit_max
    @property
    def supported_qpts(self):
        return self.packet_pacing_caps.supported_qpts


cdef class TMCaps(PyverbsObject):
    @property
    def max_rndv_hdr_size(self):
        return self.tm_caps.max_rndv_hdr_size
    @property
    def max_num_tags(self):
        return self.tm_caps.max_num_tags
    @property
    def flags(self):
        return self.tm_caps.flags
    @property
    def max_ops(self):
        return self.tm_caps.max_ops
    @property
    def max_sge(self):
        return self.tm_caps.max_sge


cdef class CQModerationCaps(PyverbsObject):
    @property
    def max_cq_count(self):
        return self.cq_mod_caps.max_cq_count
    @property
    def max_cq_period(self):
        return self.cq_mod_caps.max_cq_period


cdef class DeviceAttrEx(PyverbsObject):
    @property
    def orig_attr(self):
        attr = DeviceAttr()
        attr.dev_attr = self.dev_attr.orig_attr
        return attr
    @property
    def comp_mask(self):
        return self.dev_attr.comp_mask
    @comp_mask.setter
    def comp_mask(self, val):
        self.dev_attr.comp_mask = val
    @property
    def odp_caps(self):
        caps = ODPCaps()
        caps.odp_caps = self.dev_attr.odp_caps
        caps.xrc_odp_caps = self.dev_attr.xrc_odp_caps
        return caps
    @property
    def completion_timestamp_mask(self):
        return self.dev_attr.completion_timestamp_mask
    @property
    def hca_core_clock(self):
        return self.dev_attr.hca_core_clock
    @property
    def device_cap_flags_ex(self):
        return self.dev_attr.device_cap_flags_ex
    @property
    def tso_caps(self):
        caps = TSOCaps()
        caps.tso_caps = self.dev_attr.tso_caps
        return caps
    @property
    def pci_atomic_caps(self):
        caps = PCIAtomicCaps()
        caps.caps = self.dev_attr.pci_atomic_caps
        return caps
    @property
    def rss_caps(self):
        caps = RSSCaps()
        caps.rss_caps = self.dev_attr.rss_caps
        return caps
    @property
    def max_wq_type_rq(self):
        return self.dev_attr.max_wq_type_rq
    @property
    def packet_pacing_caps(self):
        caps = PacketPacingCaps()
        caps.packet_pacing_caps = self.dev_attr.packet_pacing_caps
        return caps
    @property
    def raw_packet_caps(self):
        return self.dev_attr.raw_packet_caps
    @property
    def tm_caps(self):
        caps = TMCaps()
        caps.tm_caps = self.dev_attr.tm_caps
        return caps
    @property
    def cq_mod_caps(self):
        caps = CQModerationCaps()
        caps.cq_mod_caps = self.dev_attr.cq_mod_caps
        return caps
    @property
    def max_dm_size(self):
        return self.dev_attr.max_dm_size
    @property
    def phys_port_cnt_ex(self):
        return self.dev_attr.phys_port_cnt_ex


cdef class AllocDmAttr(PyverbsObject):
    def __init__(self, length, log_align_req = 0, comp_mask = 0):
        """
        Creates an AllocDmAttr object with the given parameters. This object
        can than be used to create a DM object.
        :param length: Length of the future device memory
        :param log_align_req: log2 of address alignment requirement
        :param comp_mask: compatibility mask
        :return: An AllocDmAttr object
        """
        super().__init__()
        self.alloc_dm_attr.length = length
        self.alloc_dm_attr.log_align_req = log_align_req
        self.alloc_dm_attr.comp_mask = comp_mask

    @property
    def length(self):
        return self.alloc_dm_attr.length

    @length.setter
    def length(self, val):
        self.alloc_dm_attr.length = val

    @property
    def log_align_req(self):
        return self.alloc_dm_attr.log_align_req

    @log_align_req.setter
    def log_align_req(self, val):
        self.alloc_dm_attr.log_align_req = val

    @property
    def comp_mask(self):
        return self.alloc_dm_attr.comp_mask

    @comp_mask.setter
    def comp_mask(self, val):
        self.alloc_dm_attr.comp_mask = val


cdef class DM(PyverbsCM):
    def __init__(self, Context context, AllocDmAttr dm_attr=None, **kwargs):
        """
        Allocate a device (direct) memory.
        :param context: The context of the device on which to allocate memory
        :param dm_attr: Attributes that define the DM
        :param kwargs: Arguments:
            * *handle*
                A valid kernel handle for a DM object in the given context.
                If passed, the DM will be imported and associated with the
                given context using ibv_import_dm.
        :return: A DM object on success
        """
        super().__init__()
        self.dm_mrs = weakref.WeakSet()

        dm_handle = kwargs.get('handle')
        if dm_handle is not None:
            self.dm = v.ibv_import_dm(context.context, dm_handle)
            if self.dm == NULL:
                raise PyverbsRDMAErrno('Failed to import DM')
            self._is_imported = True
        else:
            device_attr = context.query_device_ex()
            if device_attr.max_dm_size <= 0:
                raise PyverbsUserError('Device doesn\'t support dm allocation')
            self.dm = v.ibv_alloc_dm(<v.ibv_context*>context.context,
                                     &dm_attr.alloc_dm_attr)
            if self.dm == NULL:
                raise PyverbsRDMAErrno('Failed to allocate device memory of size '
                                       '{size}. Max available size {max}.'
                                       .format(size=dm_attr.length,
                                               max=device_attr.max_dm_size))
        self.context = context
        context.add_ref(self)

    def unimport(self):
        v.ibv_unimport_dm(self.dm)
        self.close()

    def __dealloc__(self):
        self.close()

    cpdef close(self):
        """
        Closes the underlying C object of the DM.
        In case of an imported DM, the DM won't be freed, and it's kept for the
        original DM object, in order to prevent double free by Python GC.
        """
        if self.dm != NULL:
            if self.logger:
                self.logger.debug('Closing DM')
            close_weakrefs([self.dm_mrs])
            if not self._is_imported:
                rc = v.ibv_free_dm(self.dm)
                if rc != 0:
                    raise PyverbsRDMAError('Failed to free dm', rc)
            self.dm = NULL
            self.context = None

    cdef add_ref(self, obj):
        if isinstance(obj, DMMR):
            self.dm_mrs.add(obj)

    def copy_to_dm(self, dm_offset, data, length):
        rc = v.ibv_memcpy_to_dm(<v.ibv_dm *>self.dm, <uint64_t>dm_offset,
                                <char *>data, <size_t>length)
        if rc != 0:
            raise PyverbsRDMAError('Failed to copy to dm', rc)

    def copy_from_dm(self, dm_offset, length):
        cdef char *data =<char*>malloc(length)
        memset(data, 0, length)
        rc = v.ibv_memcpy_from_dm(<void *>data, <v.ibv_dm *>self.dm,
                                  <uint64_t>dm_offset, <size_t>length)
        if rc != 0:
            raise PyverbsRDMAError('Failed to copy from dm', rc)
        res = data[:length]
        free(data)
        return res

    @property
    def handle(self):
        return self.dm.handle


cdef class PortAttr(PyverbsObject):
    @property
    def state(self):
        return self.attr.state
    @property
    def max_mtu(self):
        return self.attr.max_mtu
    @property
    def active_mtu(self):
        return self.attr.active_mtu
    @property
    def gid_tbl_len(self):
        return self.attr.gid_tbl_len
    @property
    def port_cap_flags(self):
        return self.attr.port_cap_flags
    @property
    def max_msg_sz(self):
        return self.attr.max_msg_sz
    @property
    def bad_pkey_cntr(self):
        return self.attr.bad_pkey_cntr
    @property
    def qkey_viol_cntr(self):
        return self.attr.qkey_viol_cntr
    @property
    def pkey_tbl_len(self):
        return self.attr.pkey_tbl_len
    @property
    def lid(self):
        return self.attr.lid
    @property
    def sm_lid(self):
        return self.attr.sm_lid
    @property
    def lmc(self):
        return self.attr.lmc
    @property
    def max_vl_num(self):
        return self.attr.max_vl_num
    @property
    def sm_sl(self):
        return self.attr.sm_sl
    @property
    def subnet_timeout(self):
        return self.attr.subnet_timeout
    @property
    def init_type_reply(self):
        return self.attr.init_type_reply
    @property
    def active_width(self):
        return self.attr.active_width
    @property
    def active_speed(self):
        return self.attr.active_speed
    @property
    def phys_state(self):
        return self.attr.phys_state
    @property
    def link_layer(self):
        return self.attr.link_layer
    @property
    def flags(self):
        return self.attr.flags
    @property
    def port_cap_flags2(self):
        return self.attr.port_cap_flags2
    @property
    def active_speed_ex(self):
        return self.attr.active_speed_ex

    def __str__(self):
        print_format = '{:<24}: {:<20}\n'
        return print_format.format('Port state', port_state_to_str(self.attr.state)) +\
            print_format.format('Max MTU', translate_mtu(self.attr.max_mtu)) +\
            print_format.format('Active MTU', translate_mtu(self.attr.active_mtu)) +\
            print_format.format('SM lid', self.attr.sm_lid) +\
            print_format.format('Port lid', self.attr.lid) +\
            print_format.format('lmc', hex(self.attr.lmc)) +\
            print_format.format('Link layer', translate_link_layer(self.attr.link_layer)) +\
            print_format.format('Max message size', hex(self.attr.max_msg_sz)) +\
            print_format.format('Port cap flags', translate_port_cap_flags(self.attr.port_cap_flags)) +\
            print_format.format('Port cap flags 2', translate_port_cap_flags2(self.attr.port_cap_flags2)) +\
            print_format.format('max VL num', self.attr.max_vl_num) +\
            print_format.format('Bad Pkey counter', self.attr.bad_pkey_cntr) +\
            print_format.format('Qkey violations counter', self.attr.qkey_viol_cntr) +\
            print_format.format('GID table len', self.attr.gid_tbl_len) +\
            print_format.format('Pkey table len', self.attr.pkey_tbl_len) +\
            print_format.format('SM sl', self.attr.sm_sl) +\
            print_format.format('Subnet timeout', self.attr.subnet_timeout) +\
            print_format.format('Init type reply', self.attr.init_type_reply) +\
            print_format.format('Active width', width_to_str(self.attr.active_width)) +\
            print_format.format('Active speed', speed_to_str(self.attr.active_speed, self.attr.active_speed_ex)) +\
            print_format.format('Phys state', phys_state_to_str(self.attr.phys_state)) +\
            print_format.format('Flags', self.attr.flags)


cdef class GIDEntry(PyverbsObject):
    def __init__(self, subnet_prefix=0, interface_id=0, gid_index=0,
                 port_num=0, gid_type=0, ndev_ifindex=0):
        super().__init__()
        self.entry.gid._global.subnet_prefix = subnet_prefix
        self.entry.gid._global.interface_id = interface_id
        self.entry.gid_index = gid_index
        self.entry.port_num = port_num
        self.entry.gid_type = gid_type
        self.entry.ndev_ifindex = ndev_ifindex

    @property
    def gid_subnet_prefix(self):
        return self.entry.gid._global.subnet_prefix

    @property
    def gid_interface_id(self):
        return self.entry.gid._global.interface_id

    @property
    def gid_index(self):
        return self.entry.gid_index

    @property
    def port_num(self):
        return self.entry.port_num

    @property
    def gid_type(self):
        return self.entry.gid_type

    @property
    def ndev_ifindex(self):
        return self.entry.ndev_ifindex

    def gid_str(self):
        return gid_str(self.gid_subnet_prefix, self.gid_interface_id)

    def __str__(self):
        print_format = '{:<24}: {:<20}\n'
        return print_format.format('GID', self.gid_str()) +\
            print_format.format('GID Index', self.gid_index) +\
            print_format.format('Port number', self.port_num) +\
            print_format.format('GID type', translate_gid_type(
                                self.gid_type)) +\
            print_format.format('Ndev ifindex', self.ndev_ifindex)


cdef class AsyncEvent(PyverbsObject):
    def __init__(self, event_type=0):
        super().__init__()
        self.event.event_type = event_type

    def ack(self):
        v.ibv_ack_async_event(&self.event)

    @property
    def event_type(self):
        return self.event.event_type

    def __str__(self):
        print_format = '{:<24}: {:<20}\n'
        return print_format.format('Event Type', translate_event_type(
                                   self.event.event_type))


def translate_gid_type(gid_type):
    types = {e.IBV_GID_TYPE_IB: 'IB', e.IBV_GID_TYPE_ROCE_V1: 'RoCEv1',
             e.IBV_GID_TYPE_ROCE_V2: 'RoCEv2'}
    try:
        return types[gid_type]
    except KeyError:
        return f'Unknown gid_type ({gid_type})'


def guid_format(num):
    """
    Get GUID representation of the given number, including change of endianness.
    :param num: Number to change to GUID format.
    :return: GUID-formatted string.
    """
    num = be64toh(num)
    hex_str = "%016x" % (num)
    hex_array = [hex_str[i:i+2] for i in range(0, len(hex_str), 2)]
    hex_array = [''.join(x) for x in zip(hex_array[0::2], hex_array[1::2])]
    return ':'.join(hex_array)


def translate_transport_type(transport_type):
    l = {0: 'IB', 1: 'IWARP', 2: 'USNIC', 3: 'USNIC UDP'}
    try:
        return l[transport_type]
    except KeyError:
        return 'Unknown'


def translate_node_type(node_type):
    l = {1: 'CA', 2: 'Switch', 3: 'Router', 4: 'RNIC', 5: 'USNIC',
         6: 'USNIC UDP'}
    try:
        return l[node_type]
    except KeyError:
        return 'Unknown'


def guid_to_hex(node_guid):
    return hex(node_guid).replace('L', '').replace('0x', '')


def port_state_to_str(port_state):
    l = {0: 'NOP', 1: 'Down', 2: 'Init', 3: 'Armed', 4: 'Active', 5: 'Defer'}
    try:
        return '{s} ({n})'.format(s=l[port_state], n=port_state)
    except KeyError:
        return 'Invalid state ({s})'.format(s=port_state)


def translate_mtu(mtu):
    l = {1: 256, 2: 512, 3: 1024, 4: 2048, 5: 4096}
    try:
        return '{s} ({n})'.format(s=l[mtu], n=mtu)
    except KeyError:
        return 'Invalid MTU ({m})'.format(m=mtu)


def translate_link_layer(ll):
    l = {0: 'Unspecified', 1:'InfiniBand', 2:'Ethernet'}
    try:
        return l[ll]
    except KeyError:
        return 'Invalid link layer ({ll})'.format(ll=ll)


def translate_port_cap_flags(flags):
    l = {e.IBV_PORT_SM: 'IBV_PORT_SM',
         e.IBV_PORT_NOTICE_SUP: 'IBV_PORT_NOTICE_SUP',
         e.IBV_PORT_TRAP_SUP: 'IBV_PORT_TRAP_SUP',
         e.IBV_PORT_OPT_IPD_SUP: 'IBV_PORT_OPT_IPD_SUP',
         e.IBV_PORT_AUTO_MIGR_SUP: 'IBV_PORT_AUTO_MIGR_SUP',
         e.IBV_PORT_SL_MAP_SUP: 'IBV_PORT_SL_MAP_SUP',
         e.IBV_PORT_MKEY_NVRAM: 'IBV_PORT_MKEY_NVRAM',
         e.IBV_PORT_PKEY_NVRAM: 'IBV_PORT_PKEY_NVRAM',
         e.IBV_PORT_LED_INFO_SUP: 'IBV_PORT_LED_INFO_SUP',
         e.IBV_PORT_SYS_IMAGE_GUID_SUP: 'IBV_PORT_SYS_IMAGE_GUID_SUP',
         e.IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP: 'IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP',
         e.IBV_PORT_EXTENDED_SPEEDS_SUP: 'IBV_PORT_EXTENDED_SPEEDS_SUP',
         e.IBV_PORT_CAP_MASK2_SUP: 'IBV_PORT_CAP_MASK2_SUP',
         e.IBV_PORT_CM_SUP: 'IBV_PORT_CM_SUP',
         e.IBV_PORT_SNMP_TUNNEL_SUP: 'IBV_PORT_SNMP_TUNNEL_SUP',
         e.IBV_PORT_REINIT_SUP: 'IBV_PORT_REINIT_SUP',
         e.IBV_PORT_DEVICE_MGMT_SUP: 'IBV_PORT_DEVICE_MGMT_SUP',
         e.IBV_PORT_VENDOR_CLASS_SUP: 'IBV_PORT_VENDOR_CLASS_SUP',
         e.IBV_PORT_DR_NOTICE_SUP: 'IBV_PORT_DR_NOTICE_SUP',
         e.IBV_PORT_CAP_MASK_NOTICE_SUP: 'IBV_PORT_CAP_MASK_NOTICE_SUP',
         e.IBV_PORT_BOOT_MGMT_SUP: 'IBV_PORT_BOOT_MGMT_SUP',
         e.IBV_PORT_LINK_LATENCY_SUP: 'IBV_PORT_LINK_LATENCY_SUP',
         e.IBV_PORT_CLIENT_REG_SUP: 'IBV_PORT_CLIENT_REG_SUP',
         e.IBV_PORT_IP_BASED_GIDS: 'IBV_PORT_IP_BASED_GIDS'}
    return str_from_flags(flags, l)


def translate_port_cap_flags2(flags):
    l = {e.IBV_PORT_SET_NODE_DESC_SUP: 'IBV_PORT_SET_NODE_DESC_SUP',
         e.IBV_PORT_INFO_EXT_SUP: 'IBV_PORT_INFO_EXT_SUP',
         e.IBV_PORT_VIRT_SUP: 'IBV_PORT_VIRT_SUP',
         e.IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP: 'IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP',
         e.IBV_PORT_LINK_WIDTH_2X_SUP: 'IBV_PORT_LINK_WIDTH_2X_SUP',
         e.IBV_PORT_LINK_SPEED_HDR_SUP: 'IBV_PORT_LINK_SPEED_HDR_SUP',
         e.IBV_PORT_LINK_SPEED_NDR_SUP: 'IBV_PORT_LINK_SPEED_NDR_SUP'}
    return str_from_flags(flags, l)


def translate_device_caps(flags):
    l = {e.IBV_DEVICE_RESIZE_MAX_WR: 'IBV_DEVICE_RESIZE_MAX_WR',
         e.IBV_DEVICE_BAD_PKEY_CNTR: 'IBV_DEVICE_BAD_PKEY_CNTR',
         e.IBV_DEVICE_BAD_QKEY_CNTR: 'IBV_DEVICE_BAD_QKEY_CNTR',
         e.IBV_DEVICE_RAW_MULTI: 'IBV_DEVICE_RAW_MULTI',
         e.IBV_DEVICE_AUTO_PATH_MIG: 'IBV_DEVICE_AUTO_PATH_MIG',
         e.IBV_DEVICE_CHANGE_PHY_PORT: 'IBV_DEVICE_CHANGE_PHY_PORT',
         e.IBV_DEVICE_UD_AV_PORT_ENFORCE: 'IBV_DEVICE_UD_AV_PORT_ENFORCE',
         e.IBV_DEVICE_CURR_QP_STATE_MOD: 'IBV_DEVICE_CURR_QP_STATE_MOD',
         e.IBV_DEVICE_SHUTDOWN_PORT: 'IBV_DEVICE_SHUTDOWN_PORT',
         e.IBV_DEVICE_INIT_TYPE: 'IBV_DEVICE_INIT_TYPE',
         e.IBV_DEVICE_PORT_ACTIVE_EVENT: 'IBV_DEVICE_PORT_ACTIVE_EVENT',
         e.IBV_DEVICE_SYS_IMAGE_GUID: 'IBV_DEVICE_SYS_IMAGE_GUID',
         e.IBV_DEVICE_RC_RNR_NAK_GEN: 'IBV_DEVICE_RC_RNR_NAK_GEN',
         e.IBV_DEVICE_SRQ_RESIZE: 'IBV_DEVICE_SRQ_RESIZE',
         e.IBV_DEVICE_N_NOTIFY_CQ: 'IBV_DEVICE_N_NOTIFY_CQ',
         e.IBV_DEVICE_MEM_WINDOW: 'IBV_DEVICE_MEM_WINDOW',
         e.IBV_DEVICE_UD_IP_CSUM: 'IBV_DEVICE_UD_IP_CSUM',
         e.IBV_DEVICE_XRC: 'IBV_DEVICE_XRC',
         e.IBV_DEVICE_MEM_MGT_EXTENSIONS: 'IBV_DEVICE_MEM_MGT_EXTENSIONS',
         e.IBV_DEVICE_MEM_WINDOW_TYPE_2A: 'IBV_DEVICE_MEM_WINDOW_TYPE_2A',
         e.IBV_DEVICE_MEM_WINDOW_TYPE_2B: 'IBV_DEVICE_MEM_WINDOW_TYPE_2B',
         e.IBV_DEVICE_RC_IP_CSUM: 'IBV_DEVICE_RC_IP_CSUM',
         e.IBV_DEVICE_RAW_IP_CSUM: 'IBV_DEVICE_RAW_IP_CSUM',
         e.IBV_DEVICE_MANAGED_FLOW_STEERING: 'IBV_DEVICE_MANAGED_FLOW_STEERING'}
    return str_from_flags(flags, l)


def str_from_flags(flags, dictionary):
    str_flags = "\n  "
    for bit in dictionary:
        if flags & bit:
            str_flags += dictionary[bit]
            str_flags += '\n  '
    return str_flags


def phys_state_to_str(phys):
    l =  {1: 'Sleep', 2: 'Polling', 3: 'Disabled',
          4: 'Port configuration training', 5: 'Link up',
          6: 'Link error recovery', 7: 'Phy test'}
    try:
        return '{s} ({n})'.format(s=l[phys], n=phys)
    except KeyError:
        return 'Invalid physical state'


def width_to_str(width):
    l = {1: '1X', 2: '4X', 4: '8X', 8: '12X', 16: '2X'}
    try:
        return '{s} ({n})'.format(s=l[width], n=width)
    except KeyError:
        return 'Invalid width'


def speed_to_str(active_speed, active_speed_ex):
    real_speed = active_speed if not active_speed_ex else active_speed_ex
    l = {0: '0.0 Gbps', 1: '2.5 Gbps', 2: '5.0 Gbps', 4: '5.0 Gbps',
         8: '10.0 Gbps', 16: '14.0 Gbps', 32: '25.0 Gbps', 64: '50.0 Gbps',
         128: '100.0 Gbps', 256: '200.0 Gbps'}
    try:
        return '{s} ({n})'.format(s=l[real_speed], n=real_speed)
    except KeyError:
        return 'Invalid speed'


def get_device_list():
    """
    :return: list of IB_devices on current node
             each list element contains a Device with:
                 device name
                 device node type
                 device transport type
                 device guid
                 device index
    """
    cdef int count = 0;
    cdef v.ibv_device **dev_list;
    dev_list = v.ibv_get_device_list(&count)
    if dev_list == NULL:
            raise PyverbsRDMAError('Failed to get devices list')
    devices = []
    try:
        for i in range(count):
            name = dev_list[i].name
            node = dev_list[i].node_type
            transport = dev_list[i].transport_type
            guid = be64toh(v.ibv_get_device_guid(dev_list[i]))
            index = v.ibv_get_device_index(dev_list[i])
            devices.append(Device(name, guid, node, transport, index))
    finally:
        v.ibv_free_device_list(dev_list)
    return devices


def rdma_get_devices():
    """
    Get the RDMA devices.
    :return: list of Device objects.
    """
    cdef int count
    cdef v.ibv_context **ctx_list
    ctx_list = cm.rdma_get_devices(&count)
    if ctx_list == NULL:
        raise PyverbsRDMAErrno('Failed to get device list')
    devices = []
    for i in range(count):
        name = ctx_list[i].device.name
        node = ctx_list[i].device.node_type
        transport = ctx_list[i].device.transport_type
        guid = be64toh(v.ibv_get_device_guid(ctx_list[i].device))
        index = v.ibv_get_device_index(ctx_list[i].device)
        devices.append(Device(name, guid, node, transport, index))
    cm.rdma_free_devices(ctx_list)
    return devices


def translate_event_type(event_type):
    types = {
        e.IBV_EVENT_CQ_ERR: 'IBV_EVENT_CQ_ERR',
        e.IBV_EVENT_QP_FATAL: 'IBV_EVENT_QP_FATAL',
        e.IBV_EVENT_QP_REQ_ERR: 'IBV_EVENT_QP_REQ_ERR',
        e.IBV_EVENT_QP_ACCESS_ERR: 'IBV_EVENT_QP_ACCESS_ERR',
        e.IBV_EVENT_COMM_EST: 'IBV_EVENT_COMM_EST',
        e.IBV_EVENT_SQ_DRAINED: 'IBV_EVENT_SQ_DRAINED',
        e.IBV_EVENT_PATH_MIG: 'IBV_EVENT_PATH_MIG',
        e.IBV_EVENT_PATH_MIG_ERR: 'IBV_EVENT_PATH_MIG_ERR',
        e.IBV_EVENT_DEVICE_FATAL: 'IBV_EVENT_DEVICE_FATAL',
        e.IBV_EVENT_PORT_ACTIVE: 'IBV_EVENT_PORT_ACTIVE',
        e.IBV_EVENT_PORT_ERR: 'IBV_EVENT_PORT_ERR',
        e.IBV_EVENT_LID_CHANGE: 'IBV_EVENT_LID_CHANGE',
        e.IBV_EVENT_PKEY_CHANGE: 'IBV_EVENT_PKEY_CHANGE',
        e.IBV_EVENT_SM_CHANGE: 'IBV_EVENT_SM_CHANGE',
        e.IBV_EVENT_SRQ_ERR: 'IBV_EVENT_SRQ_ERR',
        e.IBV_EVENT_SRQ_LIMIT_REACHED: 'IBV_EVENT_SRQ_LIMIT_REACHED',
        e.IBV_EVENT_QP_LAST_WQE_REACHED: '.IBV_EVENT_QP_LAST_WQE_REACHED',
        e.IBV_EVENT_CLIENT_REREGISTER: 'IBV_EVENT_CLIENT_REREGISTER',
        e.IBV_EVENT_GID_CHANGE: 'IBV_EVENT_GID_CHANGE',
        e.IBV_EVENT_WQ_FATAL: 'IBV_EVENT_WQ_FATAL'
    }
    try:
        return types[event_type]
    except KeyError:
        return f'Unknown event_type ({event_type})'


cdef class FdArr(PyverbsObject):
    """
    Represent ibv_fd_arr struct. This class is used a pointer to the file descriptor array
    """
    def __init__(self, arr=[], count=0):
        super().__init__()
        cdef int *dst
        self.attr.arr = <int*>malloc(count * sizeof(int))
        if self.attr.arr == NULL:
            raise PyverbsRDMAErrno('Failed to malloc FD list')
        dst = self.attr.arr
        for i in range(count):
            dst[i]= arr[i]
        self.attr.count = count

    def __dealloc__(self):
        self.close()

    cpdef close(self):
        free(self.attr.arr)

    def __str__(self):
        print_format = '{:20}: {:<20}\n'
        return print_format.format('Number of fd in arr', self.attr.count) +\
               print_format.format('FDs in arr', [self.attr.arr[i] for i in range(self.attr.count)])

    @property
    def arr(self):
        return [self.attr.arr[i] for i in range(self.attr.count)]

    @property
    def count(self):
        return self.attr.count
