ObjFW  All files named "src/OFRunLoop.m"

History for src/OFRunLoop.m

2021-01-02
22:06
Update copyright file: [53e222eb32] check-in: [27b401c7c2] user: js, branch: amiga-library, size: 37270 [annotate] [blame] [check-ins using] [diff]
22:04
Update copyright file: [b43754d684] check-in: [374e1a1bfa] user: js, branch: trunk, size: 37318 [annotate] [blame] [check-ins using] [diff]
2020-07-06
23:50
Merge trunk into branch "amiga-library" file: [348cd20ee8] check-in: [c536c268a0] user: js, branch: amiga-library, size: 37359 [annotate] [blame] [check-ins using] [diff]
2020-06-28
15:03
Use OF_DIRECT(_MEMBERS) where appropriate file: [ae4dcb6d52] check-in: [b6cb3addd0] user: js, branch: trunk, size: 37407 [annotate] [blame] [check-ins using] [diff]
2020-06-20
23:16
Add all public constants to linklib file: [bc1499b7d8] check-in: [547e079e08] user: js, branch: amiga-library, size: 37341 [annotate] [blame] [check-ins using] [diff]
13:56
OFRunLoop: Make of_run_loop_mode_default const file: [1ed99b4d7a] check-in: [d6709240fd] user: js, branch: trunk, size: 37389 [annotate] [blame] [check-ins using] [diff]
2020-04-29
23:59
Add OFSPXSocket file: [8701d2b9f0] check-in: [857f8edc09] user: js, branch: trunk, size: 37383 [annotate] [blame] [check-ins using] [diff]
2020-04-26
19:39
Remove redundant arguments from blocks

Arguments that can just be captured by the block don't need to be
repeated as an argument. A lot of arguments passed to a delegate are
therefore not needed for a block. file: [964085efa2] check-in: [d7ddb3dbc7] user: js, branch: trunk, size: 37506 [annotate] [blame] [check-ins using] [diff]

18:10
Move accept and listen OF{TCP -> Stream}Socket file: [ae15c876fb] check-in: [13a8f43898] user: js, branch: trunk, size: 37647 [annotate] [blame] [check-ins using] [diff]
16:21
Add OFSequencedPacketSocket

This is intended for SCTP and SPX. file: [9b755653ca] check-in: [e5b2ee56ff] user: js, branch: trunk, size: 37620 [annotate] [blame] [check-ins using] [diff]

2020-04-25
17:05
Add OFDatagramSocket as base class for OFUDPSocket

This makes it easier to reuse code for other datagram sockets, namely
IPX. file: [9886e0ee45] check-in: [b02c4b05bb] user: js, branch: trunk, size: 34180 [annotate] [blame] [check-ins using] [diff]

2020-04-24
00:21
Add OFIPStreamSocket

This is a new superclass for OFTCPSocket to allow sharing code with
other IP stream socket types, namely SCTP. file: [b3743d07b5] check-in: [3dfe642dd3] user: js, branch: trunk, size: 34180 [annotate] [blame] [check-ins using] [diff]

2020-01-02
01:51
Update copyright file: [ac74ecd3ae] check-in: [c7f0229795] user: js, branch: trunk, size: 34144 [annotate] [blame] [check-ins using] [diff]
2019-09-07
23:28
Fix async connect with epoll file: [d7aa5cb83d] check-in: [846125bed6] user: js, branch: trunk, size: 34141 [annotate] [blame] [check-ins using] [diff]
2019-09-01
15:09
OFRunLoop: Add support for Exec Signals file: [747027d6fd] check-in: [816a96ff90] user: js, branch: trunk, size: 33483 [annotate] [blame] [check-ins using] [diff]
2019-08-31
13:09
OFRunLoop: Fix _timersQueueMutex being nil file: [a4f683594b] check-in: [c5e8215ddc] user: js, branch: trunk, size: 28380 [annotate] [blame] [check-ins using] [diff]
2019-06-17
02:33
Remove underscores from class names file: [67b18d3257] check-in: [17d57e01ff] user: js, branch: trunk, size: 28244 [annotate] [blame] [check-ins using] [diff]
2019-03-08
00:35
Use dot syntax file: [355a023a1d] check-in: [bceb7ed4c9] user: js, branch: trunk, size: 28279 [annotate] [blame] [check-ins using] [diff]
2019-01-07
22:59
Partially fix sockets on Nintendo 3DS/Wii

This does not fully fix it yet, but at least the socket tests in the
test suite pass on 3DS now. file: [f76ad8e6f6] check-in: [ab89c47f42] user: js, branch: trunk, size: 28332 [annotate] [blame] [check-ins using] [diff]

2019-01-03
19:13
Update copyright file: [7120aa762e] check-in: [0509d7a844] user: js, branch: trunk, size: 28155 [annotate] [blame] [check-ins using] [diff]
2018-12-18
21:17
Use OFData instead of a buffer for async UDP sends

This avoids the entire problem of keeping the buffer alive until the
send finished. file: [6ee3abdf2e] check-in: [0f3ae90eef] user: js, branch: trunk, size: 28149 [annotate] [blame] [check-ins using] [diff]

17:10
Slightly decrease binary size file: [8d0f224f35] check-in: [3501205f07] user: js, branch: trunk, size: 28047 [annotate] [blame] [check-ins using] [diff]
16:41
Add -[OFStream asyncWriteString:] file: [e91294dd59] check-in: [6b35b78f94] user: js, branch: trunk, size: 29968 [annotate] [blame] [check-ins using] [diff]
14:14
Use OFData instead of a buffer for async writes

This avoids the entire problem of keeping the buffer alive until the
write finished. file: [7000e17b8e] check-in: [f218986f51] user: js, branch: trunk, size: 27395 [annotate] [blame] [check-ins using] [diff]

2018-12-11
22:57
Include an exception in delegate methods

Otherwise, there would be two methods for every operation: One for
success and one for failure. It also makes it easy to forget about
handling failure, so it's better to always pass an optional exception. file: [2b70c16414] check-in: [064dbe5127] user: js, branch: trunk, size: 27224 [annotate] [blame] [check-ins using] [diff]

2018-12-08
18:55
OFUDPSocket: Use a delegate for async operations file: [536375a07c] check-in: [da2dd2dde5] user: js, branch: trunk, size: 28607 [annotate] [blame] [check-ins using] [diff]
16:53
Separate error methods for async method delegates file: [1cb22455c7] check-in: [2b6a12065e] user: js, branch: trunk, size: 28777 [annotate] [blame] [check-ins using] [diff]
16:05
OFTCPSocket: Use a delegate for async operations file: [ab8e75f5ed] check-in: [27153bf8cf] user: js, branch: trunk, size: 28713 [annotate] [blame] [check-ins using] [diff]
2018-12-07
01:33
OFStream: Use a delegate for async operations

The target / selector approach had several drawbacks:

* It was inconvenient to use, as for every read or write, a target,
selector and context would need to be specified.
* It lacked any kind of type-safety and would not even warn about using
a callback method with the wrong number of parameters.
* It encouraged using a different callback method for each read or
write call, which results in code that is hard to follow and also
slower (as it needs to recreate the async operation with a new
callback every time). file: [692cbbd5b1] check-in: [d16ad96cbd] user: js, branch: trunk, size: 28736 [annotate] [blame] [check-ins using] [diff]

2018-10-07
02:06
Remove resolver.m

Instead, OFDNSResolver is used for everything now. file: [b99d9d1539] check-in: [6e9ee122eb] user: js, branch: trunk, size: 28426 [annotate] [blame] [check-ins using] [diff]

2018-09-24
00:13
OFRunLoop: Add support for modes file: [54ecb2a574] check-in: [3fb96dff3c] user: js, branch: trunk, size: 28368 [annotate] [blame] [check-ins using] [diff]
2018-08-26
12:46
Initial support for async connect without threads file: [f211a21b64] check-in: [1e79c0a969] user: js, branch: trunk, size: 24834 [annotate] [blame] [check-ins using] [diff]
2018-08-05
19:27
OFRunLoop: More robust handling of cancels file: [900992f7d6] check-in: [1bf3b2ac7c] user: js, branch: trunk, size: 23806 [annotate] [blame] [check-ins using] [diff]
2018-07-28
17:38
Rename of_{udp_ -> }socket_address file: [3e6c2ca250] check-in: [b16f2b9e25] user: js, branch: trunk, size: 23298 [annotate] [blame] [check-ins using] [diff]
2018-02-25
13:46
OFRunLoop: Reset _stop after -[run]

This allows calling -[run] from a callback to run the loop for a while,
without the run that called the callback being stopped. file: [3fae23d4fe] check-in: [184011467a] user: js, branch: trunk, size: 23330 [annotate] [blame] [check-ins using] [diff]

2018-01-03
19:49
Update copyright notice file: [06b6c0f243] check-in: [7e5c81e186] user: js, branch: trunk, size: 23313 [annotate] [blame] [check-ins using] [diff]
2017-11-19
11:04
Do not conform to OFReadyFor*Observing by default

Instead of letting OFStream conform to it, which itself does not really
conform to it, let all the subclasses that actually do conform to it. file: [5ad7583705] check-in: [69749b6a5b] user: js, branch: trunk, size: 23290 [annotate] [blame] [check-ins using] [diff]

2017-10-22
15:05
Make Apple GCC with -Wshadow happy file: [2a10d90f42] check-in: [a06354b42a] user: js, branch: trunk, size: 22974 [annotate] [blame] [check-ins using] [diff]
14:09
Make Apple GCC with -Wshadow happy file: [15a7c5ffb7] check-in: [31c0f5b89e] user: js, branch: 0.90, size: 16533 [annotate] [blame] [check-ins using] [diff]
2017-10-17
00:33
Do not use implicit method return types

Instead, explicitly declare them, as OF_ASSUME_NONNULL_{BEGIN,END} does
not apply to implicit return types. This means that after this commit,
all init methods have a nonnull return type, as they should have. file: [03e94e120d] check-in: [2f4e0df8be] user: js, branch: trunk, size: 22990 [annotate] [blame] [check-ins using] [diff]

2017-09-24
17:35
OFUDPSocket: Add support for async sending file: [2cf7056bd3] check-in: [842c55dd83] user: js, branch: trunk, size: 22976 [annotate] [blame] [check-ins using] [diff]
15:42
OFRunLoop: Move #ifdef to the right place file: [fbe3b55d16] check-in: [1e3159ac95] user: js, branch: trunk, size: 20831 [annotate] [blame] [check-ins using] [diff]
15:13
OFStream: More flexible repeating async writes file: [20e274a7c7] check-in: [1084b23ef7] user: js, branch: trunk, size: 20831 [annotate] [blame] [check-ins using] [diff]
13:15
Return a bool from async write handlers

This allows performing another write with the same buffer, length and
callback, which is useful for asynchronously writing in chunks. file: [8ab72d20c1] check-in: [47db5636d7] user: js, branch: trunk, size: 20777 [annotate] [blame] [check-ins using] [diff]

12:24
OFStream: Add support for async writes file: [9b934c5330] check-in: [481225349f] user: js, branch: trunk, size: 20669 [annotate] [blame] [check-ins using] [diff]
11:24
Change type for async exceptions to id file: [1a169f665d] check-in: [f8498bb114] user: js, branch: trunk, size: 16808 [annotate] [blame] [check-ins using] [diff]
2017-09-23
22:07
Support for passing a context to async IO handlers file: [35d1810bb5] check-in: [958da109d3] user: js, branch: trunk, size: 17035 [annotate] [blame] [check-ins using] [diff]
2017-08-01
12:10
OFRunLoop: Fix missing imports file: [2bcc651795] check-in: [b641d5c17b] user: js, branch: 0.90, size: 16549 [annotate] [blame] [check-ins using] [diff]
2017-07-31
11:45
OFRunLoop: Ignore EINTR file: [208fa9c8e0] check-in: [5bab29322e] user: js, branch: 0.90, size: 16492 [annotate] [blame] [check-ins using] [diff]
2017-05-21
21:28
Prefix private methods with of_ instead of OF_

This matches Apple's style. file: [50df1150e8] check-in: [6b77a5dd8b] user: js, branch: trunk, size: 16285 [annotate] [blame] [check-ins using] [diff]

2017-05-13
22:38
Reduce retain + autorelease file: [750b7da4cf] check-in: [504e13cf00] user: js, branch: trunk, size: 16285 [annotate] [blame] [check-ins using] [diff]
2017-05-07
20:10
Small code style change

Casts are now written like types in variable declarations. file: [f31ca790af] check-in: [4af49a13c3] user: js, branch: trunk, size: 16308 [annotate] [blame] [check-ins using] [diff]

2017-02-04
21:37
OFRunLoop: Refactor read queue handling file: [af29aae29a] check-in: [6ae356af85] user: js, branch: trunk, size: 16237 [annotate] [blame] [check-ins using] [diff]
2017-01-09
17:36
Update copyright

Forgot to add 2017, even though I already did quite some changes in
2017. file: [bedf74278b] check-in: [44f45c2e35] user: js, branch: trunk, size: 18868 [annotate] [blame] [check-ins using] [diff]

2016-04-18
17:22
OFRunLoop: Small clean up file: [0893597d95] check-in: [7d387ea44c] user: js, branch: 0.8, size: 18382 [annotate] [blame] [check-ins using] [diff]
17:20
OFRunLoop: Small clean up file: [84cb722e01] check-in: [ba813e24da] user: js, branch: trunk, size: 18862 [annotate] [blame] [check-ins using] [diff]
2016-02-21
10:36
OFRunLoop: Fix a missing deadline != nil check file: [3185d7f56f] check-in: [bb8753c099] user: js, branch: trunk, size: 18946 [annotate] [blame] [check-ins using] [diff]
2016-02-10
22:25
Add -[OFRunLoop runUntilDate:] file: [5f1e1fd3c7] check-in: [0f44c12d9f] user: js, branch: trunk, size: 18919 [annotate] [blame] [check-ins using] [diff]
2016-01-03
00:41
Update copyright

While at it, also update the mail address. file: [1d17371e17] check-in: [2a27cf3000] user: js, branch: trunk, size: 18466 [annotate] [blame] [check-ins using] [diff]

2015-01-03
20:57
Update copyright file: [4ce7477fa1] check-in: [cfd374b906] user: js, branch: trunk, size: 18462 [annotate] [blame] [check-ins using] [diff]
2014-06-21
21:43
Move all macros from OFObject.h to macros.h

This means that OFObject.h imports macros.h now, making it unnecessary
to manually import macros.h in almost every file. And while at it, also
import autorelease.h in OFObject.h, so that this doesn't need to be
manually imported in almost every file as well. file: [c3c6b10589] check-in: [13ee56edf3] user: js, branch: trunk, size: 18456 [annotate] [blame] [check-ins using] [diff]

2014-01-30
22:02
OFUDPSocket: Add async resolve / receive file: [6b234d3dd8] check-in: [ff3c507941] user: js, branch: trunk, size: 18500 [annotate] [blame] [check-ins using] [diff]
12:26
Rename of_tcpsocket* -> of_tcp_socket_* file: [4801e3917e] check-in: [7908c035e4] user: js, branch: trunk, size: 15869 [annotate] [blame] [check-ins using] [diff]
2014-01-29
15:54
Generalize OFKernelEventObserver

It is no longer limited to streams now. file: [870ab6e96c] check-in: [c694569d86] user: js, branch: trunk, size: 15867 [annotate] [blame] [check-ins using] [diff]

2014-01-28
22:50
Rename OFStreamObserver -> OFKernelEventObserver file: [50e05df3a1] check-in: [96e20b8093] user: js, branch: trunk, size: 15930 [annotate] [blame] [check-ins using] [diff]
2014-01-16
23:09
Add of_time_interval_t.

This is used instead for time intervals now instead of doubles. file: [e29f8ae799] check-in: [dc31ce3d34] user: js, branch: trunk, size: 15822 [annotate] [blame] [check-ins using] [diff]

2014-01-04
00:24
Update copyright. file: [5f0333dffc] check-in: [3b97fc3cd9] user: js, branch: trunk, size: 15803 [annotate] [blame] [check-ins using] [diff]
2013-10-29
23:46
Clean up OF_ENSURE() vs. assert() a little. file: [cac020d21b] check-in: [a427cfc86a] user: js, branch: trunk, size: 15797 [annotate] [blame] [check-ins using] [diff]
2013-08-15
19:00
Move private methods into private headers. file: [ece7ab01e9] check-in: [1d7a1cbca0] user: js, branch: trunk, size: 15803 [annotate] [blame] [check-ins using] [diff]
2013-07-04
13:59
Remove useless barriers.

We don't care about the order here, we only care about getting the
update. The barrier is only useful to force the order. file: [3252e51e8a] check-in: [0fea69d149] user: js, branch: trunk, size: 15745 [annotate] [blame] [check-ins using] [diff]

2013-05-01
21:05
OFRunLoop: Work correctly for threads && !sockets.

This was only an issue with --enable-threads --disable-sockets. file: [410ce014df] check-in: [56ec27cbdf] user: js, branch: trunk, size: 15861 [annotate] [blame] [check-ins using] [diff]

2013-04-30
22:47
observeWithTimeout: -> observeForTimeInterval:. file: [fcdc461826] check-in: [ab9ad6e515] user: js, branch: trunk, size: 15486 [annotate] [blame] [check-ins using] [diff]
2013-04-26
20:40
Make sure +[OFThread sleep*] is always available.

This means that even if --disable-threads has been specified, it is
possible to use +[OFThread sleep*] to sleep the current (and only)
thread. file: [76c781112c] check-in: [71d45a29d1] user: js, branch: trunk, size: 15474 [annotate] [blame] [check-ins using] [diff]

19:42
Make it possible to disable sockets. file: [e463b5f0e9] check-in: [590c377d8a] user: js, branch: trunk, size: 15475 [annotate] [blame] [check-ins using] [diff]
2013-04-18
19:54
Fix --disable-threads. file: [9ced28ca2c] check-in: [c1f5396016] user: js, branch: trunk, size: 14803 [annotate] [blame] [check-ins using] [diff]
2013-04-07
21:21
Fix Win32 #include hell. file: [274be6b78a] check-in: [ec6b265428] user: js, branch: trunk, size: 14743 [annotate] [blame] [check-ins using] [diff]
2013-03-14
19:25
Add a few memory barriers. file: [3b393cf990] check-in: [27138ee85b] user: js, branch: trunk, size: 14714 [annotate] [blame] [check-ins using] [diff]
2013-03-04
17:20
Replace BOOL with bool.

The only places where BOOL is left are those where they are required by
the ABI. file: [d42000199a] check-in: [c5ef582958] user: js, branch: trunk, size: 14622 [annotate] [blame] [check-ins using] [diff]

2013-02-12
18:22
Prefix all ivars with an underscore. file: [d21ff8bef4] check-in: [e40729d406] user: js, branch: trunk, size: 14618 [annotate] [blame] [check-ins using] [diff]
2013-01-13
14:59
Make it possible to stop run loops. file: [9ee569b5cb] check-in: [3c6ad38d92] user: js, branch: trunk, size: 14393 [annotate] [blame] [check-ins using] [diff]
2013-01-12
20:53
Clean up the feature #ifdef mess. file: [9373453d76] check-in: [b8ce2359f3] user: js, branch: trunk, size: 14310 [annotate] [blame] [check-ins using] [diff]
20:21
Fix --disable-threads. file: [1f0d5617f1] check-in: [85b8efadbc] user: js, branch: trunk, size: 14250 [annotate] [blame] [check-ins using] [diff]
2013-01-09
22:24
Update copyright. file: [37689eeb3f] check-in: [813c00ccf0] user: js, branch: trunk, size: 13981 [annotate] [blame] [check-ins using] [diff]
2012-12-20
13:57
OFTimer: Make rescheduling possible. file: [ce73e14376] check-in: [4572170728] user: js, branch: trunk, size: 13975 [annotate] [blame] [check-ins using] [diff]
2012-12-19
20:55
Make it possible to cancel async requests. file: [cee8e6c735] check-in: [dc7b33cd6b] user: js, branch: trunk, size: 13569 [annotate] [blame] [check-ins using] [diff]
2012-12-16
13:39
OFRunLoop: Use OFMutex instead of @synchronized. file: [5845195cdf] check-in: [35ad639b7c] user: js, branch: trunk, size: 13134 [annotate] [blame] [check-ins using] [diff]
2012-11-24
00:07
-[OFSortedList addObject:] -> -[insertObject:].

The rationale behind this is that otherwise, there are two methods
called addObject: with a different signature, the one from
OFMutableArray and the one from OFSortedList. As OFSortedList is
actually using insertion sort and all other methods on an OFList start
with insert anyway, this is also more consistent. file: [a5c17b66d7] check-in: [7a8a5a2995] user: js, branch: trunk, size: 12903 [annotate] [blame] [check-ins using] [diff]

2012-10-30
18:50
Async I/O: Pass a context. file: [c937fefc13] check-in: [13ea2fc8b1] user: js, branch: trunk, size: 13378 [annotate] [blame] [check-ins using] [diff]
2012-10-17
20:16
Pass exceptions on async I/O.

This makes it possible to handle exceptions that occurred during async
I/O in the specified handler. file: [5d7da15761] check-in: [6343e04dcd] user: js, branch: trunk, size: 12900 [annotate] [blame] [check-ins using] [diff]

2012-09-20
00:06
ObjC 1 fix.

Don't let OFRunLoop conform to OFStreamObserverDelegate, as it does not
fully implement the protocol and we have no @optional in ObjC 1. file: [0f13518563] check-in: [932eb2bd6f] user: js, branch: trunk, size: 12100 [annotate] [blame] [check-ins using] [diff]

2012-09-19
23:02
Make async I/O possible without blocks.

Async connecting is still missing. file: [019d6ee84a] check-in: [4d9a641d87] user: js, branch: trunk, size: 12122 [annotate] [blame] [check-ins using] [diff]

2012-09-17
15:48
Add -[asyncReadIntoBuffer:exactLength:block:]. file: [2fb0c01789] check-in: [be6adc6e06] user: js, branch: trunk, size: 9277 [annotate] [blame] [check-ins using] [diff]
2012-09-16
22:26
Every OFThread now always has a run loop. file: [4507c3903b] check-in: [4c8f9edda8] user: js, branch: trunk, size: 7770 [annotate] [blame] [check-ins using] [diff]
21:59
Make it possible to invalidate OFTimers. file: [cf11bcd288] check-in: [8658d1a22a] user: js, branch: trunk, size: 7990 [annotate] [blame] [check-ins using] [diff]
15:27
Prefix all private methods with OF_. file: [021a7791a3] check-in: [c137da5e5b] user: js, branch: trunk, size: 7966 [annotate] [blame] [check-ins using] [diff]
13:23
Slightly refactor OFRunLoop. file: [f5145d052f] check-in: [0cfbbb367a] user: js, branch: trunk, size: 7957 [annotate] [blame] [check-ins using] [diff]
11:45
Fix missing imports. file: [646227ddee] check-in: [5a19a8a2a5] user: js, branch: trunk, size: 8181 [annotate] [blame] [check-ins using] [diff]
10:19
Add -[OFTCPSocket asyncAcceptWithBlock:]. file: [35be43bbba] check-in: [5d8349a8f6] user: js, branch: trunk, size: 8157 [annotate] [blame] [check-ins using] [diff]
2012-09-14
07:03
Create the current OFRunLoop on demand. file: [5d28216a68] check-in: [2193480a94] user: js, branch: trunk, size: 6756 [annotate] [blame] [check-ins using] [diff]
05:36
OFRunLoop: Remove the key for the stream.

As the stream is used as a key, this references the stream. This
resulted in the stream never being deallocated, even though it was not
used anymore. The advantage of not removing it was that the next async
read on the stream would have been slightly faster by saving one malloc. file: [317802665c] check-in: [13eb2bf77b] user: js, branch: trunk, size: 6593 [annotate] [blame] [check-ins using] [diff]

05:20
Implement async reading (into buffers and lines). file: [0049670d02] check-in: [a2b309b38a] user: js, branch: trunk, size: 6487 [annotate] [blame] [check-ins using] [diff]
2012-09-12
06:41
OFRunLoop: Reduce the time the lock is held. file: [e04d2c2152] check-in: [34e548c51d] user: js, branch: trunk, size: 2855 [annotate] [blame] [check-ins using] [diff]
06:11
Run loops have a stream observer now.

This makes async I/O possible! file: [af64aebbb7] check-in: [df53f06922] user: js, branch: trunk, size: 2880 [annotate] [blame] [check-ins using] [diff]

06:11
OFRunLoop: Remove timer before possible read.

A timer always needs to be removed before its fireDate is changed,
otherwise, this will break the ordering in the OFSortedList. file: [30c14bee93] check-in: [55e7d380e4] user: js, branch: trunk, size: 3141 [annotate] [blame] [check-ins using] [diff]

2012-09-11
16:48
Added: Add OFTimer and OFRunLoop. file: [b78dbdb727] check-in: [a4494ec477] user: js, branch: trunk, size: 3047 [annotate] [blame] [check-ins using]