util_queue.c revision 02b636c64ad657301ef5f5e6c2d14c6bec693fff
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <assert.h>
#include <syslog.h>
#include <synch.h>
#include <time.h>
#include <umem.h>
#include "queue.h"
#include "iscsi_conn.h"
#include "utility.h"
#include "target.h"
#include "t10.h"
/*
* Constants
*/
int qlog_lvl = 0;
int queue_num;
void
{
}
{
target_queue_t *q =
if (q == NULL)
return (NULL);
(void) pthread_mutex_lock(&q_mutex);
(void) pthread_mutex_unlock(&q_mutex);
return (q);
}
void
{
(void) pthread_mutex_lock(&q_mutex);
}
(void) pthread_mutex_unlock(&q_mutex);
}
/*
* []----
* | queue_message_set -- add a given message to the queue.
* []----
*/
void
void *data)
{
return;
(void) pthread_mutex_lock(&q->q_mutex);
} else {
}
(void) pthread_mutex_unlock(&q->q_mutex);
}
/*
* []----
* | queue_message_get -- retrieve the first message in the queue
* []----
*/
msg_t *
{
msg_t *m;
(void) pthread_mutex_lock(&q->q_mutex);
m = q->q_head;
if (m == NULL) {
(void) pthread_mutex_unlock(&q->q_mutex);
return (NULL);
}
(void) pthread_mutex_unlock(&q->q_mutex);
return (m);
}
/*
* []----
* | queue_message_try_get -- see if there's a message available
* []----
*/
msg_t *
{
msg_t *m;
if (sema_trywait(&q->q_sema) != 0)
return (NULL);
(void) pthread_mutex_lock(&q->q_mutex);
m = q->q_head;
(void) pthread_mutex_unlock(&q->q_mutex);
return (m);
}
/*
* []----
* | queue_walker_free -- Run through a queue and free certain messages.
* |
* | Users of the queues should not walk the queue structure themselves
* | unless they also need to grab the lock. To prevent that level of
* | knowledge of the queue structures this method is provided to enable
* | other subsystems to walk the queue looking for messages which need
* | to be deleted.
* []----
*/
void
void *v1)
{
msg_t *m; /* current working message */
msg_t *n; /* next message */
(void) pthread_mutex_lock(&q->q_mutex);
m = q->q_head;
while (m) {
if (m == q->q_head) {
else
} else {
else
}
n = m->msg_next;
m = n;
} else {
m = m->msg_next;
}
}
(void) pthread_mutex_unlock(&q->q_mutex);
}
/*
* []----
* | queue_reset -- Flush a queue of all command messages messages.
* []----
*/
void
{
msg_t *m;
msg_t *n;
(void) pthread_mutex_lock(&q->q_mutex);
m = q->q_head;
while (m != NULL) {
switch (m->msg_type) {
case msg_cmd_data_out:
case msg_cmd_send:
if (m == q->q_head) {
else
} else {
else
}
n = m->msg_next;
m = n;
break;
case msg_reset_lu:
case msg_shutdown:
case msg_lu_add:
case msg_lu_remove:
case msg_lu_online:
case msg_thick_provo:
/*
* Don't flush the control messages
*/
m = m->msg_next;
break;
default:
"---- Unexpected msg type %d ----", m->msg_type);
m = m->msg_next;
break;
}
}
(void) pthread_mutex_unlock(&q->q_mutex);
}
void
{
}
/*
* []----
* | queue_free -- free resources used by queue structure
* []----
*/
void
{
msg_t *m;
msg_t *n;
(void) pthread_mutex_lock(&q->q_mutex);
m = q->q_head;
while (m != NULL) {
(*free_func)(m);
n = m->msg_next;
m = n;
}
(void) pthread_mutex_unlock(&q->q_mutex);
(void) pthread_mutex_destroy(&q->q_mutex);
(void) sema_destroy(&q->q_sema);
free(q);
}
void
{
char buf[80];
/* LINTED variable format specifier */
}
/*
* []----
* | queue_str -- helper function which sends a string to the queue
* []----
*/
void
{
int len;
char *m;
(void) pthread_mutex_lock(&q_mutex);
}
(void) pthread_mutex_unlock(&q_mutex);
last_h = h;
} else {
}
}
/*
* []------------------------------------------------------------------[]
* | Specialized free routines for queue data. |
* | It is possible for a shutdown to start because the STE thread |
* | receives an error while reading from the socket. If at the same |
* | time the connection poll thread is processing a PDU it could place |
* | a msg_ste_datain package on the STE queue. When the STE hits the |
* | shutdown message first it will exit and we need to clean up |
* | anything on that queue which means freeing memory in the |
* | appropriate manner. This is just one example and there are several |
* | others. Another method to deal with this would be to have a closed |
* | flag such that any futher calls to queue_message_set would return |
* | an error. This would require any calls to queue_message_set() deal |
* | with this condition. The approach used here seems cleaner. |
* | The drawback to this approach is that if any new messages are |
* | added then the developer had better add it to these routines as |
* | appropriate. |
* []------------------------------------------------------------------[]
*/
/*
* []----
* | sess_queue_data_remove -- free any message data left on the sess queue
* |
* | XXX This should be recoded so that we're doing the cleanup within
* | the session code. Peal off any messages and deal with them there.
* []----
*/
void
{
char **buf;
switch (m->msg_type) {
default:
m->msg_type);
break;
case msg_shutdown:
case msg_shutdown_rsp:
case msg_ste_media_error:
" of type %d", m->msg_type);
break;
case msg_cmd_data_out:
break;
case msg_initiator_name:
case msg_initiator_alias:
case msg_target_name:
break;
case msg_mgmt_rqst:
break;
case msg_mgmt_rply:
break;
case msg_reset_targ:
case msg_reset_lu:
/* ---- these are safe to ignore, no data to free ---- */
break;
}
}
/*
* []----
* | conn_queue_data_remove -- free any message data left on the conn queue
* []----
*/
void
{
switch (m->msg_type) {
case msg_cmd_data_rqst:
case msg_cmd_data_out:
case msg_cmd_cmplt:
break;
case msg_mgmt_rqst:
break;
default:
m->msg_type);
break;
}
}