/** * @brief Applier function to release invalidated ports. * This is used to break retainment cycles. * @private @memberof MIDIPort * @param item A pointer to the MIDIPort to check. * @param info A pointer to the MIDIPort that is connected * to the port to check. * @retval 0 on success. */ static int _port_apply_check( void * item, void * info ) { struct MIDIPort * port = item; struct MIDIPort * source = info; if( port->mode & MIDI_PORT_INVALID ) { /* retain the port, before removing to avoid recursion * release the port *after* it was removed from the list */ MIDIPortRetain( port ); MIDIListRemove( source->ports, port ); MIDIPortRelease( port ); } return 0; }
/** * @brief Applier function to send to a port. * This is used when a port sends data to all connected ports. * If the port to send to was invalidated before, remove it from the * list of connected ports. Send the message to the port otherwise. * @private @memberof MIDIPort * @param item A pointer to the MIDIPort to send to. * @param info A pointer to the MIDIPortApplyParams structure * that was passed to MIDIListApply. * @retval 0 on success. */ static int _port_apply_send( void * item, void * info ) { struct MIDIPort * port = item; struct MIDIPortApplyParams * params = info; if( port->mode & MIDI_PORT_INVALID ) { MIDIPortRetain( port ); MIDIListRemove( params->port->ports, port ); MIDIPortRelease( port ); return 0; } else if( port != params->port ) { return MIDIPortReceiveFrom( port, params->port, params->type, params->object ); } else { /* avoid sending messages to self */ return 0; } }
/** * @brief Destroy a MIDIDriver instance. * Free all resources occupied by the driver and release all referenced objects. * @public @memberof MIDIDriver * @param driver The driver. */ void MIDIDriverDestroy( struct MIDIDriver * driver ) { MIDIPrecondReturn( driver != NULL, EFAULT, (void)0 ); if( driver->destroy != NULL ) { (*driver->destroy)( driver ); } if( driver->clock != NULL ) { MIDIClockRelease( driver->clock ); } if( driver->rls != NULL ) { MIDIRunloopSourceInvalidate( driver->rls ); MIDIRunloopSourceRelease( driver->rls ); } MIDIPortInvalidate( driver->port ); MIDIPortRelease( driver->port ); free( driver ); }