2.2. OPENIPMI CONCEPTS
for an object owned by a particular domain, that object and anything it belongs to will be marked in-use. So, for instance, in a callback for a sensor, the sensor is in-use, the entity the sensor belongs to is in-use, the management controller the sensor is on is in-use, and the domain the sensor is in will be in-use. No other sensors, entities, or management controllers will necessarily be marked in-use. Outside of callbacks, the library is free to change pointers, change information, add and remove objects, or make whatever general changes that are required.
So how do you mark an IPMI object in-use? If you are handling incoming IPMI callbacks you generally don’t have to worry about this. But say you are handling outside input, such as a user interface. What then? If the pointers can change, how do you keep a reference to something?
OpenIPMI provides two identifiers for IPMI objects. One is a pointer, but a pointer is only good inside a callback. The other is an OpenIPMI id; the id is good outside callbacks. But the only thing you can do with an id is pass it to a function that will call a callback for you with the pointer. You can convert a pointer to an id (inside a callback, of course) so you should do that if you need to save a reference to the object. Note that there are some functions that take ids that do this for you (such as ipmi_sensor_id_reading_get(), other sensor functions, hot-swap functions, and a few others); these are provided for your convenience. Almost all sensor, control, and entity functions that you would generally call asynchronously support these ipmi_xxx_id function. The operation is exactly the same as the same operation without the _id, it simply takes the id instead of the direct pointer. See the ipmiif.h include file to see if the function you desire exists.
This mechanism, though a little inconvenient, almost guarantees that you will not forget to decrement a use count. It nicely encapsulates the locked operation in a function1. You have to return from the function unless you exit, longjmp, or throw an exception that falls through the callback, and you shouldn’t do those things.
You must do this whether you are using locking or not, because the library uses this mechanism to determine whether the id you are holding is good. Once it converts the id to the pointer, your pointer is guaranteed to be good until the function returns.
The functions to convert an id to a pointer are named ipmi_xxx_pointer_cb(), where “xxx” is control, entity, domain, or sensor. Unlike many other callbacks, the callback function you provide to these functions will be called immediately in the same thread of execution, this callback is not delayed or spawned off to another thread. So, for instance, you can use data on the stack of the calling function and pass it to the callback function to use.
For instance, suppose you have a callback registered with the domain for finding when new entities are ready, and you are looking for a specific entity. The code might look like:
_ entity_change(enum ipmi_update e op,
_ ipmi domain_t
_ ipmi entity_t
i p m i _ e n t i t y _ i d _ t m y _ e n t i t y _ i d = I P M I _ E N T I T Y _ I D _ I N V A L I D ;
1This is how locking works in Ada95 and Java, although their mechanisms are a little more convenient since they are built into the language