@@ -52,6 +52,76 @@ fn clone_chan[T](chan[T] c) -> chan[T] {
52
52
ret unsafe:: reinterpret_cast ( cloned) ;
53
53
}
54
54
55
+ // Spawn a task and immediately return a channel for communicating to it
56
+ fn worker[ T ] ( fn ( port[ T ] ) f) -> rec ( task task, chan[ T ] chan) {
57
+ // FIXME: This is frighteningly unsafe and only works for
58
+ // a few cases
59
+
60
+ type opaque = int ;
61
+
62
+ // FIXME: This terrible hackery is because worktask can't currently
63
+ // have type params
64
+ type wordsz1 = int ;
65
+ type wordsz2 = rec ( int a, int b) ;
66
+ type wordsz3 = rec ( int a, int b, int c) ;
67
+ type wordsz4 = rec ( int a, int b, int c, int d) ;
68
+ type opaquechan_1wordsz = chan [ chan[ wordsz1] ] ;
69
+ type opaquechan_2wordsz = chan [ chan[ wordsz2] ] ;
70
+ type opaquechan_3wordsz = chan [ chan[ wordsz3] ] ;
71
+ type opaquechan_4wordsz = chan [ chan[ wordsz4] ] ;
72
+
73
+ fn worktask1 ( opaquechan_1wordsz setupch, opaque fptr) {
74
+ let * fn ( port[ wordsz1] ) f = unsafe :: reinterpret_cast ( fptr) ;
75
+ auto p = port[ wordsz1] ( ) ;
76
+ setupch <| chan( p) ;
77
+ ( * f) ( p) ;
78
+ }
79
+
80
+ fn worktask2 ( opaquechan_2wordsz setupch, opaque fptr) {
81
+ let * fn ( port[ wordsz2] ) f = unsafe :: reinterpret_cast ( fptr) ;
82
+ auto p = port[ wordsz2] ( ) ;
83
+ setupch <| chan( p) ;
84
+ ( * f) ( p) ;
85
+ }
86
+
87
+ fn worktask3 ( opaquechan_3wordsz setupch, opaque fptr) {
88
+ let * fn ( port[ wordsz3] ) f = unsafe :: reinterpret_cast ( fptr) ;
89
+ auto p = port[ wordsz3] ( ) ;
90
+ setupch <| chan( p) ;
91
+ ( * f) ( p) ;
92
+ }
93
+
94
+ fn worktask4 ( opaquechan_4wordsz setupch, opaque fptr) {
95
+ let * fn ( port[ wordsz4] ) f = unsafe :: reinterpret_cast ( fptr) ;
96
+ auto p = port[ wordsz4] ( ) ;
97
+ setupch <| chan( p) ;
98
+ ( * f) ( p) ;
99
+ }
100
+
101
+ auto p = port[ chan[ T ] ] ( ) ;
102
+ auto setupch = chan ( p) ;
103
+ auto fptr = unsafe :: reinterpret_cast ( ptr:: addr_of ( f) ) ;
104
+
105
+ auto Tsz = sys:: size_of[ T ] ( ) ;
106
+ auto t = if Tsz == sys:: size_of[ wordsz1] ( ) {
107
+ auto setupchptr = unsafe :: reinterpret_cast ( setupch) ;
108
+ spawn worktask1 ( setupchptr, fptr)
109
+ } else if Tsz == sys:: size_of[ wordsz2] ( ) {
110
+ auto setupchptr = unsafe :: reinterpret_cast ( setupch) ;
111
+ spawn worktask2 ( setupchptr, fptr)
112
+ } else if Tsz == sys:: size_of[ wordsz3] ( ) {
113
+ auto setupchptr = unsafe :: reinterpret_cast ( setupch) ;
114
+ spawn worktask3 ( setupchptr, fptr)
115
+ } else if Tsz == sys:: size_of[ wordsz4] ( ) {
116
+ auto setupchptr = unsafe :: reinterpret_cast ( setupch) ;
117
+ spawn worktask4 ( setupchptr, fptr)
118
+ } else {
119
+ fail #fmt( "unhandled type size %u in task::worker" , Tsz )
120
+ } ;
121
+ auto ch; p |> ch;
122
+ ret rec( task = t, chan = ch) ;
123
+ }
124
+
55
125
// Local Variables:
56
126
// mode: rust;
57
127
// fill-column: 78;
0 commit comments