Commit 44c548b2 authored by Andy Wingo Wingo's avatar Andy Wingo Wingo

*.*: Ran scripts/update-macros. Oh yes. gst/gstobject.h (GST_OBJECT_GET_LOCK, GST_OBJECT_LOCK)

Original commit message from CVS:
2005-11-21  Andy Wingo  <wingo@pobox.com>

* *.h:
* *.c: Ran scripts/update-macros. Oh yes.

* gst/gstobject.h (GST_OBJECT_GET_LOCK, GST_OBJECT_LOCK)
(GST_OBJECT_TRYLOCK, GST_OBJECT_UNLOCK): Renamed from
GST_GET_LOCK, etc.

* scripts/update-macros: New script. Run it on your files to
change GST_LOCK to GST_OBJECT_LOCK, and the same for UNLOCK as
well.
parent 32d62808
2005-11-21 Andy Wingo <wingo@pobox.com>
* *.h:
* *.c: Ran scripts/update-macros. Oh yes.
* gst/gstobject.h (GST_OBJECT_GET_LOCK, GST_OBJECT_LOCK)
(GST_OBJECT_TRYLOCK, GST_OBJECT_UNLOCK): Renamed from
GST_GET_LOCK, etc.
* scripts/update-macros: New script. Run it on your files to
change GST_LOCK to GST_OBJECT_LOCK, and the same for UNLOCK as
well.
2005-11-21 Stefan Kost <ensonic@users.sf.net>
* docs/gst/Makefile.am:
......
......@@ -202,12 +202,12 @@ GST_START_TEST (test_ghost_pads)
fail_unless (gst_bin_add (GST_BIN (b1), sink));
fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
GST_LOCK (b2);
GST_OBJECT_LOCK (b2);
fail_unless (b2->numsinkpads == 1);
fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
fail_unless (b2->numsrcpads == 1);
fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
GST_UNLOCK (b2);
GST_OBJECT_UNLOCK (b2);
fsrc = gst_element_get_pad (src, "src");
fail_unless (fsrc != NULL);
......
......@@ -208,12 +208,12 @@ GST_START_TEST (test_fake_object_name_threaded_right)
/* start looping and set/get name repeatedly */
for (i = 0; i < 1000; ++i) {
GST_LOCK (object);
GST_OBJECT_LOCK (object);
g_free (GST_OBJECT_NAME (object));
GST_OBJECT_NAME (object) = g_strdup ("main");
THREAD_SWITCH ();
name = g_strdup (GST_OBJECT_NAME (object));
GST_UNLOCK (object);
GST_OBJECT_UNLOCK (object);
fail_unless (strcmp (name, "main") == 0,
"Name got changed while lock held during run %d", i);
......@@ -261,8 +261,8 @@ gst_object_name_compare (GstObject * o, GstObject * p)
{
gint result;
GST_LOCK (o);
GST_LOCK (p);
GST_OBJECT_LOCK (o);
GST_OBJECT_LOCK (p);
if (o->name == NULL && p->name == NULL) {
result = 0;
......@@ -274,8 +274,8 @@ gst_object_name_compare (GstObject * o, GstObject * p)
result = strcmp (o->name, p->name);
}
GST_UNLOCK (p);
GST_UNLOCK (o);
GST_OBJECT_UNLOCK (p);
GST_OBJECT_UNLOCK (o);
return result;
}
......
......@@ -151,7 +151,7 @@ Objects
internal consistency when multiple threads call API function on the object.
For objects that extend the GStreamer base object class this lock can be
obtained with the macros GST_LOCK() and GST_UNLOCK(). For other object that do
obtained with the macros GST_OBJECT_LOCK() and GST_OBJECT_UNLOCK(). For other object that do
not extend from the base GstObject class these macros can be different.
* refcounting
......@@ -236,9 +236,9 @@ Objects
Accessing the property is therefore allowed with the following code example:
GST_LOCK (pad);
GST_OBJECT_LOCK (pad);
direction = GST_RPAD_DIRECTION (pad);
GST_UNLOCK (pad);
GST_OBJECT_UNLOCK (pad);
* Property lifetime
......@@ -263,11 +263,11 @@ Objects
lock is released, the peer could be unreffed and disposed, making the
pointer obtained in the critical section point to invalid memory.
GST_LOCK (pad);
GST_OBJECT_LOCK (pad);
peer = GST_RPAD_PEER (pad);
if (peer)
gst_object_ref (GST_OBJECT (peer));
GST_UNLOCK (pad);
GST_OBJECT_UNLOCK (pad);
... use peer ...
if (peer)
......@@ -292,9 +292,9 @@ Objects
Accessing the name of an object makes a copy of the name. The caller of the
function should g_free() the name after usage.
GST_LOCK (object)
GST_OBJECT_LOCK (object)
name = g_strdup (object->name);
GST_UNLOCK (object)
GST_OBJECT_UNLOCK (object)
... use name ...
g_free (name);
......@@ -350,7 +350,7 @@ Objects
that whenever we reacquire the lock, we check for updates to the cookie to
decide if we are still iterating the right list.
GST_LOCK (lock);
GST_OBJECT_LOCK (lock);
/* grab list and cookie */
cookie = object->list_cookie;
list = object-list;
......@@ -358,14 +358,14 @@ Objects
GstObject *item = GST_OBJECT (list->data);
/* need to ref the item before releasing the lock */
gst_object_ref (item);
GST_UNLOCK (lock);
GST_OBJECT_UNLOCK (lock);
... use/change item here...
/* release item here */
gst_object_unref (item);
GST_LOCK (lock);
GST_OBJECT_LOCK (lock);
if (cookie != object->list_cookie) {
/* handle rollback caused by concurrent modification
* of the list here */
......@@ -380,7 +380,7 @@ Objects
list = g_list_next (list);
}
}
GST_UNLOCK (lock);
GST_OBJECT_UNLOCK (lock);
* GstIterator
......
......@@ -1092,10 +1092,10 @@ GST_CLASS_GET_LOCK
GST_CLASS_LOCK
GST_CLASS_TRYLOCK
GST_CLASS_UNLOCK
GST_LOCK
GST_OBJECT_LOCK
GST_TRYLOCK
GST_UNLOCK
GST_GET_LOCK
GST_OBJECT_UNLOCK
GST_OBJECT_GET_LOCK
gst_object_set_name
gst_object_get_name
......
......@@ -104,7 +104,7 @@
functions, e.g. object properties. Be sure to lock properly here,
since applications will change those properties in a different thread
than the thread which does the actual data passing! You can use the
<function>GST_LOCK ()</function> and <function>GST_UNLOCK
<function>GST_OBJECT_LOCK ()</function> and <function>GST_OBJECT_UNLOCK
()</function> helpers in most cases, fortunately, which grabs the
default property lock of the element.
</para>
......
......@@ -3,7 +3,7 @@
// the queue is empty
while (!queue->level_buffers) {
STATUS("queue: %s U released lock\n");
GST_UNLOCK (queue);
GST_OBJECT_UNLOCK (queue);
// thread1 is scheduled and puts a lot of buffers
// in the queue
......@@ -15,7 +15,7 @@
queue->level_buffers++;
/* we can unlock now */
GST_UNLOCK (queue);
GST_OBJECT_UNLOCK (queue);
if (tosignal) {
g_mutex_lock (queue->emptylock);
......@@ -27,7 +27,7 @@
// wait forever
g_cond_wait (queue->emptycond, queue->emptylock);
g_mutex_unlock (queue->emptylock);
GST_LOCK (queue);
GST_OBJECT_LOCK (queue);
}
......
......@@ -481,7 +481,7 @@ Fixing Threading
The following pseudo code shows an algorithm for commiting the state
change in the streaming method.
GST_LOCK (element);
GST_OBJECT_LOCK (element);
/* if we are going to PAUSED, we can commit the state change */
if (GST_STATE_TRANSITION (element) == GST_STATE_READY_TO_PAUSED) {
gst_element_commit_state (element);
......@@ -491,18 +491,18 @@ Fixing Threading
/* here we wait for the next state change */
do {
g_cond_wait (element->state_cond, GST_GET_LOCK (element));
g_cond_wait (element->state_cond, GST_OBJECT_GET_LOCK (element));
} while (GST_STATE (element) == GST_STATE_PAUSED);
/* check if we got playing */
if (GST_STATE (element) != GST_STATE_PLAYING) {
/* not playing, we can't accept the buffer */
GST_UNLOCK (element);
GST_OBJECT_UNLOCK (element);
gst_buffer_unref (buf);
return GST_FLOW_WRONG_STATE;
}
}
GST_UNLOCK (element);
GST_OBJECT_UNLOCK (element);
......
......@@ -368,7 +368,7 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
{
GstBaseSink *sink = GST_BASE_SINK (object);
GST_LOCK (sink);
GST_OBJECT_LOCK (sink);
switch (prop_id) {
case PROP_PREROLL_QUEUE_LEN:
g_value_set_uint (value, sink->preroll_queue_max_len);
......@@ -380,7 +380,7 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
GST_UNLOCK (sink);
GST_OBJECT_UNLOCK (sink);
}
static GstCaps *
......@@ -489,7 +489,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
gboolean post_paused = FALSE;
gboolean post_playing = FALSE;
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
current = GST_STATE (basesink);
next = GST_STATE_NEXT (basesink);
pending = GST_STATE_PENDING (basesink);
......@@ -521,7 +521,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
GST_STATE_PENDING (basesink) = GST_STATE_VOID_PENDING;
GST_STATE_RETURN (basesink) = GST_STATE_CHANGE_SUCCESS;
}
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
if (post_paused) {
message = gst_message_new_state_changed (GST_OBJECT_CAST (basesink),
......@@ -546,7 +546,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
stopping:
{
/* app is going to READY */
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
return FALSE;
}
}
......@@ -752,10 +752,10 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
if (!gst_base_sink_commit_state (basesink))
goto stopping;
GST_LOCK (pad);
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
GST_UNLOCK (pad);
GST_OBJECT_UNLOCK (pad);
/* it is possible that commiting the state made us go to PLAYING
* now in which case we don't need to block anymore. */
......@@ -781,10 +781,10 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
GST_DEBUG_OBJECT (basesink, "waiting to finish preroll");
GST_PREROLL_WAIT (pad);
GST_DEBUG_OBJECT (basesink, "done preroll");
GST_LOCK (pad);
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
GST_UNLOCK (pad);
GST_OBJECT_UNLOCK (pad);
}
GST_PREROLL_UNLOCK (pad);
......@@ -816,7 +816,7 @@ dropping:
}
flushing:
{
GST_UNLOCK (pad);
GST_OBJECT_UNLOCK (pad);
gst_base_sink_preroll_queue_flush (basesink, pad);
GST_PREROLL_UNLOCK (pad);
GST_DEBUG_OBJECT (basesink, "pad is flushing");
......@@ -883,12 +883,12 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
if (bclass->event)
bclass->event (basesink, event);
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
basesink->flushing = TRUE;
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
GST_PREROLL_LOCK (pad);
/* we need preroll after the flush */
......@@ -913,9 +913,9 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
/* now we are completely unblocked and the _chain method
* will return */
GST_STREAM_LOCK (pad);
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
basesink->flushing = FALSE;
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
/* we need new segment info after the flush. */
basesink->segment_start = -1;
basesink->segment_stop = -1;
......@@ -979,11 +979,11 @@ gst_base_sink_wait (GstBaseSink * basesink, GstClockTime time)
basesink->clock_id = id;
/* release the object lock while waiting */
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
ret = gst_clock_id_wait (id, NULL);
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
gst_clock_id_unref (id);
basesink->clock_id = NULL;
......@@ -1079,7 +1079,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
if (basesink->clock) {
GstClockTime base_time;
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
base_time = GST_ELEMENT_CAST (basesink)->base_time;
......@@ -1097,7 +1097,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
result = gst_base_sink_wait (basesink, stream_start + base_time);
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
GST_LOG_OBJECT (basesink, "clock entry done: %d", result);
} else {
......@@ -1128,7 +1128,7 @@ gst_base_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
if (basesink->clock) {
/* wait for last buffer to finish if we have a valid end time */
if (GST_CLOCK_TIME_IS_VALID (basesink->end_time)) {
......@@ -1136,7 +1136,7 @@ gst_base_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
basesink->end_time = GST_CLOCK_TIME_NONE;
}
}
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
break;
default:
break;
......@@ -1217,10 +1217,10 @@ gst_base_sink_chain (GstPad * pad, GstBuffer * buf)
basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
if (!(basesink->pad_mode == GST_ACTIVATE_PUSH)) {
GST_LOCK (pad);
GST_OBJECT_LOCK (pad);
g_warning ("Push on pad %s:%s, but it was not activated in push mode",
GST_DEBUG_PAD_NAME (pad));
GST_UNLOCK (pad);
GST_OBJECT_UNLOCK (pad);
result = GST_FLOW_UNEXPECTED;
goto done;
}
......@@ -1277,11 +1277,11 @@ gst_base_sink_deactivate (GstBaseSink * basesink, GstPad * pad)
/* step 1, unblock clock sync (if any) or any other blocking thing */
GST_PREROLL_LOCK (pad);
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
/* unlock any subclasses */
if (bclass->unlock)
......@@ -1428,10 +1428,10 @@ gst_base_sink_send_event (GstElement * element, GstEvent * event)
GstBaseSink *basesink = GST_BASE_SINK (element);
gboolean result;
GST_LOCK (element);
GST_OBJECT_LOCK (element);
pad = basesink->sinkpad;
gst_object_ref (pad);
GST_UNLOCK (element);
GST_OBJECT_UNLOCK (element);
result = gst_pad_push_event (pad, event);
......@@ -1464,17 +1464,17 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
case GST_FORMAT_TIME:
{
/* we can answer time format */
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
if ((clock = GST_ELEMENT_CLOCK (basesink))) {
GstClockTime now;
gint64 segment_time;
gst_object_ref (clock);
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
now = gst_clock_get_time (clock);
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
if (GST_CLOCK_TIME_IS_VALID (basesink->segment_time))
segment_time = basesink->segment_time;
else
......@@ -1492,7 +1492,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
res = TRUE;
}
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
}
default:
break;
......@@ -1653,12 +1653,12 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
bclass = GST_BASE_SINK_GET_CLASS (basesink);
GST_PREROLL_LOCK (basesink->sinkpad);
GST_LOCK (basesink);
GST_OBJECT_LOCK (basesink);
/* unlock clock wait if any */
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_OBJECT_UNLOCK (basesink);
/* unlock any subclasses */
if (bclass->unlock)
......
......@@ -812,11 +812,11 @@ gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
basesrc->clock_id = id;
/* release the object lock while waiting */
GST_UNLOCK (basesrc);
GST_OBJECT_UNLOCK (basesrc);
ret = gst_clock_id_wait (id, NULL);
GST_LOCK (basesrc);
GST_OBJECT_LOCK (basesrc);
gst_clock_id_unref (id);
basesrc->clock_id = NULL;
......@@ -853,7 +853,7 @@ gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
/* now do clocking */
GST_LOCK (basesrc);
GST_OBJECT_LOCK (basesrc);
base_time = GST_ELEMENT_CAST (basesrc)->base_time;
GST_LOG_OBJECT (basesrc,
......@@ -862,7 +862,7 @@ gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
result = gst_base_src_wait (basesrc, start + base_time);
GST_UNLOCK (basesrc);
GST_OBJECT_UNLOCK (basesrc);
GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
......@@ -892,10 +892,10 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
GST_DEBUG ("live source unlocked");
}
/* FIXME, use another variable to signal stopping */
GST_LOCK (src->srcpad);
GST_OBJECT_LOCK (src->srcpad);
if (GST_PAD_IS_FLUSHING (src->srcpad))
goto flushing;
GST_UNLOCK (src->srcpad);
GST_OBJECT_UNLOCK (src->srcpad);
}
GST_LIVE_UNLOCK (src);
......@@ -974,7 +974,7 @@ done:
flushing:
{
GST_DEBUG_OBJECT (src, "pad is flushing");
GST_UNLOCK (src->srcpad);
GST_OBJECT_UNLOCK (src->srcpad);
GST_LIVE_UNLOCK (src);
return GST_FLOW_WRONG_STATE;
}
......@@ -1129,11 +1129,11 @@ gst_base_src_unlock (GstBaseSrc * basesrc)
GST_DEBUG ("unschedule clock");
/* and unblock the clock as well, if any */
GST_LOCK (basesrc);
GST_OBJECT_LOCK (basesrc);
if (basesrc->clock_id) {
gst_clock_id_unschedule (basesrc->clock_id);
}
GST_UNLOCK (basesrc);
GST_OBJECT_UNLOCK (basesrc);
GST_DEBUG ("unlock done");
......
......@@ -1422,7 +1422,7 @@ gst_base_transform_change_state (GstElement * element,
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_LOCK (trans);
GST_OBJECT_LOCK (trans);
if (GST_PAD_CAPS (trans->sinkpad) && GST_PAD_CAPS (trans->srcpad))
trans->have_same_caps =
gst_caps_is_equal (GST_PAD_CAPS (trans->sinkpad),
......@@ -1437,7 +1437,7 @@ gst_base_transform_change_state (GstElement * element,
trans->segment_stop = -1;
trans->segment_base = 0;
trans->segment_accum = 0;
GST_UNLOCK (trans);
GST_OBJECT_UNLOCK (trans);
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
......@@ -1489,7 +1489,7 @@ gst_base_transform_set_passthrough (GstBaseTransform * trans,
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
GST_LOCK (trans);
GST_OBJECT_LOCK (trans);
if (passthrough == FALSE) {
if (bclass->transform_ip || bclass->transform)
trans->passthrough = FALSE;
......@@ -1498,7 +1498,7 @@ gst_base_transform_set_passthrough (GstBaseTransform * trans,
}
GST_DEBUG_OBJECT (trans, "set passthrough %d", trans->passthrough);
GST_UNLOCK (trans);
GST_OBJECT_UNLOCK (trans);
}
/**
......@@ -1518,9 +1518,9 @@ gst_base_transform_is_passthrough (GstBaseTransform * trans)
g_return_val_if_fail (trans != NULL, FALSE);
GST_LOCK (trans);
GST_OBJECT_LOCK (trans);
result = trans->passthrough;
GST_UNLOCK (trans);
GST_OBJECT_UNLOCK (trans);
return result;
}
......@@ -1549,7 +1549,7 @@ gst_base_transform_set_in_place (GstBaseTransform * trans, gboolean in_place)
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
GST_LOCK (trans);
GST_OBJECT_LOCK (trans);
if (in_place) {
if (bclass->transform_ip) {
......@@ -1563,7 +1563,7 @@ gst_base_transform_set_in_place (GstBaseTransform * trans, gboolean in_place)
}
}
GST_UNLOCK (trans);
GST_OBJECT_UNLOCK (trans);
}
/**
......@@ -1583,9 +1583,9 @@ gst_base_transform_is_in_place (GstBaseTransform * trans)
g_return_val_if_fail (trans != NULL, FALSE);
GST_LOCK (trans);
GST_OBJECT_LOCK (trans);
result = trans->always_in_place;
GST_UNLOCK (trans);
GST_OBJECT_UNLOCK (trans);
return result;
}
......@@ -158,10 +158,10 @@ gst_collect_pads_set_function (GstCollectPads * pads,
g_return_if_fail (pads != NULL);
g_return_if_fail (GST_IS_COLLECT_PADS (pads));
GST_LOCK (pads);
GST_OBJECT_LOCK (pads);
pads->func = func;
pads->user_data = user_data;
GST_UNLOCK (pads);
GST_OBJECT_UNLOCK (pads);
}
/**
......@@ -197,14 +197,14 @@ gst_collect_pads_add_pad (GstCollectPads * pads, GstPad * pad, guint size)
data->pad = pad;
data->buffer = NULL;
GST_LOCK (pads);
GST_OBJECT_LOCK (pads);
pads->data = g_slist_append (pads->data, data);
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_chain));
gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_event));
gst_pad_set_element_private (pad, data);
pads->numpads++;