/* -*-C-*-
-$Id: os2cthrd.c,v 1.1 1994/11/28 03:42:55 cph Exp $
+$Id: os2cthrd.c,v 1.2 1994/12/02 20:41:49 cph Exp $
Copyright (c) 1994 Massachusetts Institute of Technology
/* Scheme side of channel thread interface */
#include "os2.h"
-\f
+
+static msg_list_t * new_list (void);
+static msg_t * new_message (void);
+
void
OS2_initialize_channel_thread_messages (void)
{
return (context);
}
+void
+OS2_channel_thread_close (Tchannel channel)
+{
+ channel_context_t * context = (CHANNEL_OPERATOR_CONTEXT (channel));
+ /* Closing handle should force input thread to kill itself. */
+ STD_API_CALL (dos_close, (CHANNEL_HANDLE (channel)));
+ if ((CHANNEL_CONTEXT_READAHEAD (context)) != 0)
+ OS2_destroy_message (CHANNEL_CONTEXT_READAHEAD (context));
+ OS2_close_qid (CHANNEL_CONTEXT_READER_QID (context));
+ OS_free (context);
+}
+\f
long
-channel_thread_read (Tchannel channel, char * buffer, size_t size)
+OS2_channel_thread_read (Tchannel channel, char * buffer, size_t size)
{
channel_context_t * context = (CHANNEL_OPERATOR_CONTEXT (channel));
qid_t qid = (CHANNEL_CONTEXT_READER_QID (context));
{
/* Wait for an acknowledgement before starting another read.
This regulates the amount of data in the queue. */
- msg_t * message = (OS2_receive_message (qid, 1));
- if ((MSG_TYPE (message)) != mt_readahead_ack)
- OS2_logic_error ("Expected readahead_ack message.");
- OS2_destroy_message (message);
+ OS2_destroy_message (OS2_wait_for_message (qid, mt_readahead_ack));
+}
+\f
+readahead_buffer_t *
+OS2_make_readahead_buffer (void)
+{
+ readahead_buffer_t * buffer = (OS_malloc (sizeof (readahead_buffer_t)));
+ (buffer -> head) = 0;
+ (buffer -> tail) = 0;
+ return (buffer);
+}
+
+int
+OS2_readahead_buffer_emptyp (readahead_buffer_t * buffer)
+{
+ return ((buffer -> head) == 0);
}
void
-channel_thread_close (Tchannel channel)
+OS2_readahead_buffer_insert (readahead_buffer_t * buffer, char c)
{
- channel_context_t * context = (CHANNEL_OPERATOR_CONTEXT (channel));
- /* Closing handle should force input thread to kill itself. */
- STD_API_CALL (dos_close, (CHANNEL_HANDLE (channel)));
- if ((CHANNEL_CONTEXT_READAHEAD (context)) != 0)
- OS2_destroy_message (CHANNEL_CONTEXT_READAHEAD (context));
- OS2_close_qid (CHANNEL_CONTEXT_READER_QID (context));
- OS_free (context);
+ if ((buffer -> head) == 0)
+ {
+ msg_list_t * tail = (new_list ());
+ (buffer -> head) = tail;
+ (buffer -> tail) = tail;
+ }
+ else if ((SM_READAHEAD_SIZE ((buffer -> tail) -> message))
+ == SM_READAHEAD_MAX)
+ {
+ msg_list_t * tail = (new_list ());
+ ((buffer -> tail) -> next) = tail;
+ (buffer -> tail) = tail;
+ }
+ {
+ msg_t * message = ((buffer -> tail) -> message);
+ ((SM_READAHEAD_DATA (message)) [(SM_READAHEAD_SIZE (message))++]) = c;
+ }
+}
+
+static msg_list_t *
+new_list (void)
+{
+ msg_list_t * cell = (OS_malloc (sizeof (msg_list_t)));
+ (cell -> message) = (new_message ());
+ (cell -> next) = 0;
+ return (cell);
+}
+
+static msg_t *
+new_message (void)
+{
+ msg_t * message = (OS2_make_readahead ());
+ (SM_READAHEAD_SIZE (message)) = 0;
+ return (message);
+}
+\f
+char
+OS2_readahead_buffer_rubout (readahead_buffer_t * buffer)
+{
+ if ((buffer -> head) == 0)
+ OS2_logic_error ("Rubout from empty readahead buffer.");
+ {
+ msg_t * message = ((buffer -> tail) -> message);
+ char c = ((SM_READAHEAD_DATA (message)) [--(SM_READAHEAD_SIZE (message))]);
+ if ((SM_READAHEAD_SIZE (message)) == 0)
+ {
+ msg_list_t * tail = (buffer -> tail);
+ msg_list_t * prev = (buffer -> head);
+ if (prev == tail)
+ (buffer -> head) = 0;
+ else
+ {
+ while ((prev -> next) != tail)
+ prev = (prev -> next);
+ (prev -> next) = 0;
+ (buffer -> tail) = prev;
+ }
+ OS_free (tail);
+ }
+ OS2_destroy_message (message);
+ return (c);
+ }
+}
+
+msg_t *
+OS2_readahead_buffer_read (readahead_buffer_t * buffer)
+{
+ msg_list_t * head = (buffer -> head);
+ if (head == 0)
+ return (new_message ());
+ else
+ {
+ msg_t * message = (head -> message);
+ (buffer -> head) = (head -> next);
+ OS_free (head);
+ return (message);
+ }
+}
+
+msg_list_t *
+OS2_readahead_buffer_read_all (readahead_buffer_t * buffer)
+{
+ msg_list_t * head = (buffer -> head);
+ (buffer -> head) = 0;
+ return (head);
}
/* -*-C-*-
-$Id: os2cthrd.h,v 1.1 1994/11/28 03:42:55 cph Exp $
+$Id: os2cthrd.h,v 1.2 1994/12/02 20:41:38 cph Exp $
Copyright (c) 1994 Massachusetts Institute of Technology
#define CHANNEL_CONTEXT_READAHEAD_INDEX(c) ((c) -> readahead_index)
#define CHANNEL_CONTEXT_EOFP(c) ((c) -> eofp)
-typedef struct
+typedef struct sm_readahead_s
{
DECLARE_MSG_HEADER_FIELDS;
ULONG size;
typedef msg_t sm_readahead_ack_t;
extern channel_context_t * OS2_make_channel_context (void);
-extern long channel_thread_read (Tchannel, char *, size_t);
+extern long OS2_channel_thread_read (Tchannel, char *, size_t);
extern void OS2_wait_for_readahead_ack (qid_t);
-extern void channel_thread_close (Tchannel);
+extern void OS2_channel_thread_close (Tchannel);
+
+typedef struct
+{
+ msg_list_t * head;
+ msg_list_t * tail;
+} readahead_buffer_t;
+
+extern readahead_buffer_t * OS2_make_readahead_buffer (void);
+extern int OS2_readahead_buffer_emptyp (readahead_buffer_t *);
+extern void OS2_readahead_buffer_insert (readahead_buffer_t *, char);
+extern char OS2_readahead_buffer_rubout (readahead_buffer_t *);
+extern msg_t * OS2_readahead_buffer_read (readahead_buffer_t *);
+extern msg_list_t * OS2_readahead_buffer_read_all (readahead_buffer_t *);
#endif /* SCM_OS2CTHRD_H */