} else {
while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
msleep (5);
+ if (err > 0)
+ wake_up_interruptible(&_stp_ctl_wq);
}
kbug("returning %d\n", err);
return err;
return 0;
}
-static int _stp_ctl_opens = 0;
static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
{
- /* only allow one reader */
- if (_stp_ctl_opens)
+ if (_stp_attached)
return -1;
- _stp_ctl_opens++;
- _stp_pid = current->pid;
- utt_overwrite_flag = 0;
+ _stp_attach();
return 0;
}
static int _stp_ctl_close_cmd (struct inode *inode, struct file *file)
{
- if (_stp_ctl_opens)
- _stp_ctl_opens--;
- _stp_pid = 0;
- if (!_stp_exit_flag)
- utt_overwrite_flag = 1;
+ if (_stp_attached)
+ _stp_detach();
return 0;
}
} else {
while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
msleep (5);
+ if (err > 0)
+ wake_up_interruptible(&_stp_ctl_wq);
}
return err;
}
return 0;
}
-static int _stp_ctl_opens = 0;
static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
{
- /* only allow one reader */
- if (_stp_ctl_opens)
+ if (_stp_attached)
return -1;
- _stp_ctl_opens++;
- _stp_pid = current->pid;
+ _stp_attach();
return 0;
}
static int _stp_ctl_close_cmd (struct inode *inode, struct file *file)
{
- if (_stp_ctl_opens)
- _stp_ctl_opens--;
- _stp_pid = 0;
+ if (_stp_attached)
+ _stp_detach();
return 0;
}
int probe_start(void);
void _stp_exit(void);
void _stp_handle_start (struct _stp_msg_start *st);
-
+static void _stp_detach(void);
+static void _stp_attach(void);
/* check for new workqueue API */
#ifdef DECLARE_DELAYED_WORK
if (!_stp_exit_called) {
int failures;
+ _stp_exit_flag = 1;
unregister_module_notifier(&_stp_module_load_nb);
/* we only want to do this stuff once */
}
}
+/*
+ * Called when stapio closes the control channel.
+ */
+static void _stp_detach(void)
+{
+ kbug("detach\n");
+ _stp_attached = 0;
+ _stp_pid = 0;
+
+ if (!_stp_exit_flag)
+ utt_overwrite_flag = 1;
+
+ cancel_delayed_work(&_stp_work);
+ wake_up_interruptible(&_stp_ctl_wq);
+}
+
+/*
+ * Called when stapio opens the control channel.
+ */
+static void _stp_attach(void)
+{
+ kbug("attach\n");
+ _stp_attached = 1;
+ _stp_pid = current->pid;
+ utt_overwrite_flag = 0;
+ queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
+}
+
/*
* _stp_work_queue - periodically check for IO or exit
* This is run by a kernel thread and may sleep.
wake_up_interruptible(&_stp_ctl_wq);
/* if exit flag is set AND we have finished with probe_start() */
- if (unlikely(_stp_exit_flag && _stp_start_finished)) {
+ if (unlikely(_stp_exit_flag && _stp_start_finished))
_stp_cleanup_and_exit(0);
- cancel_delayed_work(&_stp_work);
- flush_workqueue(_stp_wq);
- wake_up_interruptible(&_stp_ctl_wq);
- } else
+ else if (likely(_stp_attached))
queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
}
*/
void _stp_transport_close()
{
- kbug("************** transport_close *************\n");
+ kbug("%d: ************** transport_close *************\n", current->pid);
_stp_cleanup_and_exit(1);
- cancel_delayed_work(&_stp_work);
destroy_workqueue(_stp_wq);
- wake_up_interruptible(&_stp_ctl_wq);
- unregister_module_notifier(&_stp_module_load_nb);
_stp_unregister_ctl_channel();
if (_stp_utt) utt_trace_remove(_stp_utt);
_stp_free_modules();
_stp_kill_time();
_stp_print_cleanup(); /* free print buffers */
-
kbug("---- CLOSED ----\n");
}
_stp_wq = create_workqueue("systemtap");
if (!_stp_wq)
goto err3;
-
- queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
-
+
/* request symbolic information */
_stp_ask_for_symbols();
return 0;