-
Notifications
You must be signed in to change notification settings - Fork 3
/
listing1.html
executable file
·537 lines (436 loc) · 17.8 KB
/
listing1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>ListMania - /ListMania.c</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/Carbon/index.html">Carbon</a> > <a href="../../samplecode/Carbon/idxNetworking-date.html">Networking</a> > <A HREF="javascript:location.replace('index.html');">ListMania</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">ListMania</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/ListMania.c</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/ListMania.c</option>
<option value="listing2.html">/Read Me About ListMania.txt</option></select>
</p>
</form>
<p><strong><a href="ListMania.zip">Download Sample</a></strong> (“ListMania.zip”, 42.9K)<BR>
<strong><a href="ListMania.dmg">Download Sample</a></strong> (“ListMania.dmg”, 105.1K)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">/* File: ListMania.c Contains: Sample for demonstrating use of OT list utilities. Written by: Quinn "The Eskimo!" Copyright: Copyright © 1997-1999 by Apple Computer, Inc., All Rights Reserved. You may incorporate this Apple sample source code into your program(s) without restriction. This Apple sample source code has been provided "AS IS" and the responsibility for its operation is yours. You are not permitted to redistribute this Apple sample source code as "Apple sample source code" after having made changes. If you're going to re-distribute the source, we require that you make it clear in the source that the code was descended from Apple sample source code, but that you've made changes. Change History (most recent first): 2/18/2001 Chad Jones Updated for Codewarrior IDE 4.1 and Carbonized for OSX 7/22/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 *//////////////////////////////////////////////////////////////////////// Need to include to be carbonized /////////////////////////////////////////////////////////////////////// Need to include to be carbonized #if defined(__MWERKS__)# include <carbon.h># include <OpenTransport.h># include <OpenTptInternet.h># include <OpenTptSerial.h># include <SIOUX.h>#else# include <CoreServices/CoreServices.h>#endif# include <stdio.h>/////////////////////////////////////////////////////////////////////// OTDebugStr is not defined in any OT header files, but it is// exported by the libraries, so we define the prototype here.extern pascal void OTDebugStr(const char* str);/////////////////////////////////////////////////////////////////////// This MoreAssertQ is used in replacement for OTAssert under carbon because// OTAssert is not in carbon.static void MoreAssertQ(Boolean mustBeTrue){ if ( ! mustBeTrue ) { DebugStr("\pMoreAssertQ: Assertion failure."); }}/////////////////////////////////////////////////////////////////////// Notes// -----// This sample is designed to illustrate the use of the OT link-list// routines in a simple producer/consumer environment. The objects// being produced and consumed are widgets, as defined by the Widget// data type. There are two key routines: ProduceWidgets and// ConsumeWidgets. The first routine produces widgets (either by// reusing previously consumed (ie free) widgets, or by creating new// ones) and puts them on a 'pending' list. The second consumes the// widgets by grabbing them off the pending list. After consuming// the widget (in this sample, "consumption" means merely printing// to stdout), the routine returns the widget to a free list.//// This sample uses OTLIFO routines throughout. OTLIFO routines// are atomic with respect to interrupts, threads, and (most probably// even MP tasks), and are faster than the standard Mac OS equivalents// (ie Enqueue/Dequeue).//// In this sample, all the code is running at SystemTask time, however// all the list management in the critical portions of the code// (ie ProduceWidgets and ConsumeWidgets) is perfectly safe to run// at interrupt time. [ConsumeWidgets is not interrupt safe at the// moment because it uses "printf", but you can make it interrupt safe// if your definition of "consumption" is interrupt safe.]//// Another advantage of the OT list management routines is that they// support putting elements on multiple different lists simultaneously.// For example, all widgets are on the "list of all the widgets// in the system" and one of either the free list or the pending list.// OT's list management makes this very easy to do./////////////////////////////////////////////////////////////////////// The Widget data structure holds all the information for a widget// object. This includes://// o fSequenceNumber -- A unique, monotonically increasing, sequence// number for each widget that is ever created.// o fCreationTime -- The time at which the widget was created.// o fLastProducedTime -- The time at which the widget was last produced.//// The data structure also holds two link fields. The first, fNext,// is used to link together all the elements on either the pending// or free widget lists. The second link field is used to link all// of the widgets together in one long list, regardless of what their// status is.struct Widget { OTLink fNext; OTLink fAllWidgets; UInt32 fSequenceNumber; OTTimeStamp fCreationTime; OTTimeStamp fLastProducedTime;};typedef struct Widget Widget, *WidgetPtr;// The following three lists are used to hold lists of widgets.// gAllWidgetList is the list of all the widgets in the system.// gPendingWidgetList is the list of all the widgets that have// been produced and are awaiting consumption. gFreeWidgetList// is the list of all the widgets that are available for reuse// by the producer.//// A widget is always on the the gAllWidgetList (through its// fAllWidgets link) and is either on the gPendingWidgetList// or the gFreeWidgetList (through its fNext link).static OTLIFO gAllWidgetList;static OTLIFO gPendingWidgetList;static OTLIFO gFreeWidgetList;// gLastWidgetSequenceNumber holds the sequence number of the// last widget that was produced. When we produce a new widget,// we add one to this number to get the sequence number for the// new widget.static UInt32 gLastWidgetSequenceNumber;/////////////////////////////////////////////////////////////////////static void InitWidgetLists(void) // Initialises all of the widget lists to empty.{ gAllWidgetList.fHead = nil; gPendingWidgetList.fHead = nil; gFreeWidgetList.fHead = nil; gLastWidgetSequenceNumber = 0;}static WidgetPtr CreateWidget(void) // This routine creates a new widget and returns it to the // caller. The new widget is always added to the gAllWidgetList // through its fAllWidgets link, but is available to be linked to // another list through its fNext link.{ WidgetPtr result; // Allocate the memory for the widget. result = OTAllocMemInContext(sizeof(Widget),nil); MoreAssertQ(result != nil); //called if could not creat widget. // Fill out the information fields of the widget. Note the // use of OTAtomicAdd32 to increment gLastWidgetSequenceNumber // atomically. This guarantees that the sequence number is // unique, even if this routine is re-entered. OTMemzero(result, sizeof(Widget)); result->fSequenceNumber = OTAtomicAdd32(1, (long *) &gLastWidgetSequenceNumber); OTGetTimeStamp(&result->fCreationTime); // Add the widget to the list of all the widgets in the system. OTLIFOEnqueue(&gAllWidgetList, (OTLink *) &result->fAllWidgets); return (result);}static void ProduceWidgets(UInt32 howMany) // This routine produces howMany widgets and adds them // to the gPendingWidgetList.{ UInt32 i; OTLink *freeLink; WidgetPtr thisWidget; // Produce each new element in turn. for (i = 0; i < howMany; i++) { // Grab a free element off the front of the gFreeWidgetList. // If that returns nil, there is no free element and we have // to create a new widget. Otherwise, use OTGetLinkObject // to derive thisWidget from freeLink. freeLink = OTLIFODequeue(&gFreeWidgetList); if ( freeLink != nil ) { thisWidget = OTGetLinkObject(freeLink, Widget, fNext); } else { thisWidget = CreateWidget(); } // At this point thisWidget points to a free widget that is // not on the gFreeWidgetList. We now produce the widget, which in // this sample merely involves setting fLastProducedTime. OTGetTimeStamp(&thisWidget->fLastProducedTime); // Now add the widget to the list of produced widgets. OTLIFOEnqueue(&gPendingWidgetList, (OTLink *) &thisWidget->fNext); }}static void PrintWidget(WidgetPtr thisWidget) // Prints a widget to stdout.{ printf(" %03ld, Created @ %08lx%08lx, Produced @ %08lx%08lx", thisWidget->fSequenceNumber, thisWidget->fCreationTime.hi, thisWidget->fCreationTime.lo, thisWidget->fLastProducedTime.hi, thisWidget->fLastProducedTime.lo ); fflush(stdout);}static void ConsumeWidgets(void) // This routine consumes all of the widgets that have been produced.{ OTLink *listToConsume; WidgetPtr thisWidget; // First start by atomically stealing the list of pending // widgets. This removes all of the widgets on gPendingWidgetList // and returns them to us in listToConsume. Then, reverse // the list so that we consume them in the same order they // were produced. // // Note that these two API routines are defined to deal with // the empty list case correctly, so we don't have to // explicitly test it ourselves. listToConsume = OTLIFOStealList(&gPendingWidgetList); listToConsume = OTReverseList(listToConsume); while ( listToConsume != nil ) { // Given the link element, derive the actual widget object. thisWidget = OTGetLinkObject(listToConsume, Widget, fNext); // Now consume the widget. In this sample, consuming // a widget merely involves printing it to stdout. PrintWidget(thisWidget); printf("\n"); fflush(stdout); // Move along to the next list element... listToConsume = listToConsume->fNext; // ... and enqueue the most recently consumed widget on // the list of free widgets. Note that the order of these // two operations is important, because thisWidget->fNext // is the same memory location as listToConsume->fNext, so // we can't change thisWidget->fNext (by enqueuing it) // until we have extracted the linkage information from it. OTLIFOEnqueue(&gFreeWidgetList, (OTLink *) &thisWidget->fNext); }}static void DumpWidgetList(OTLIFO *list) // Dump a widget list that is linked using the fNext field. // This is appropriate for the pending and free lists of widgets.{ OTLink *link; WidgetPtr thisWidget; link = list->fHead; while ( link != nil ) { thisWidget = OTGetLinkObject(link, Widget, fNext); PrintWidget(thisWidget); printf("\n"); fflush(stdout); link = link->fNext; }}static void DumpWidgetAllLists(void) // Dump each af the three global lists.{ OTLink *link; WidgetPtr thisWidget; printf("gPendingWidgetList\n"); DumpWidgetList(&gPendingWidgetList); printf("gFreeWidgetList\n"); DumpWidgetList(&gFreeWidgetList); printf("gAllWidgetList\n"); fflush(stdout); link = gAllWidgetList.fHead; while ( link != nil ) { thisWidget = OTGetLinkObject(link, Widget, fAllWidgets); PrintWidget(thisWidget); printf("\n"); link = link->fNext; } fflush(stdout);}/////////////////////////////////////////////////////////////////////int main(void) // A simple command line shell for testing the various // routines defined above.{ OSStatus err; Boolean quitNow; char commandString[256]; #if defined(__MWERKS__) SIOUXSettings.autocloseonquit = FALSE; // don't close the SIOUX window on program termination SIOUXSettings.asktosaveonclose = FALSE; // don't offer to save on a close#endif err = InitOpenTransportInContext(kInitOTForApplicationMask, nil); if (err == noErr) { InitWidgetLists(); printf("Enter a command:\n"); printf("p) Produce 3 widgets\n"); printf("P) Produce 5 widgets\n"); printf("c) Consume all pending widgets\n"); printf("d) Dump all widget lists\n"); printf("q) Quit\n"); printf("\n"); fflush(stdout); quitNow = false; do { printf("Enter a command:\n"); fflush(stdout); if (fgets(commandString,sizeof(commandString),stdin) == nil) { commandString[0] = 0; } switch( commandString[0] ) { case 'q': case 'Q': quitNow = true; break; case 'c': case 'C': ConsumeWidgets(); break; case 'p': ProduceWidgets(3); break; case 'P': ProduceWidgets(5); break; case 'd': case 'D': DumpWidgetAllLists(); break; default: printf("Don't understand "%s".",commandString); fflush(stdout); break; } } while ( ! quitNow ); CloseOpenTransportInContext(nil); } if (err == noErr) { printf("Success.\n"); } else { printf("Failed with error %ld.\n", err); } fflush(stdout); return(0);}</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/ListMania/listing1.html%3Fid%3DDTS10000700-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/ListMania/listing1.html%3Fid%3DDTS10000700-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/ListMania/listing1.html%3Fid%3DDTS10000700-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>